11/*
2- * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+ * SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33 *
44 * SPDX-License-Identifier: Apache-2.0
55 */
66
7+ #include <stdbool.h>
8+ #include <string.h>
79#include "freertos/FreeRTOS.h"
810#include "freertos/task.h"
911#include "bldc_control.h"
@@ -32,6 +34,8 @@ typedef struct {
3234 void * zero_cross_handle ;
3335 esp_err_t (* control_operation )(void * handle );
3436 int delayCnt ; /*!< Delay count, each plus one is an interrupt function time */
37+ bool is_running ; /*!< avoid duplicate start */
38+ mcpwm_timer_event_callbacks_t * cbs ; /*!< dynamically allocated timer callbacks */
3539} bldc_control_t ;
3640
3741// Table to lookup bldc control event name
@@ -107,11 +111,17 @@ esp_err_t bldc_control_init(bldc_control_handle_t *handle, bldc_control_config_t
107111 ret = bldc_zero_cross_comparer_init (& control -> zero_cross_handle , & config -> zero_cross_comparer_config , & control -> control_param );
108112 BLDC_CHECK_GOTO (ret == ESP_OK , "bldc_zero_cross_comparer_init failed" , deinit );
109113 control -> zero_cross = & bldc_zero_cross_comparer_operation ;
110- mcpwm_timer_event_callbacks_t cbs = {
111- .on_full = & read_comparer_on_full ,
112- };
113- config -> six_step_config .upper_switch_config .bldc_mcpwm .cbs = & cbs ;
114+
115+ control -> cbs = malloc (sizeof (mcpwm_timer_event_callbacks_t ));
116+ if (!control -> cbs ) {
117+ ESP_LOGE (TAG , "malloc cbs failed" );
118+ goto deinit ;
119+ }
120+ memset (control -> cbs , 0 , sizeof (mcpwm_timer_event_callbacks_t ));
121+ control -> cbs -> on_full = & read_comparer_on_full ;
122+ config -> six_step_config .upper_switch_config .bldc_mcpwm .cbs = control -> cbs ;
114123 config -> six_step_config .upper_switch_config .bldc_mcpwm .timer_cb_user_data = (void * )control -> zero_cross_handle ;
124+
115125 break ;
116126 }
117127#if CONFIG_SOC_MCPWM_SUPPORTED
@@ -123,11 +133,17 @@ esp_err_t bldc_control_init(bldc_control_handle_t *handle, bldc_control_config_t
123133 ESP_LOGE (TAG , "error: control type must be mcpwm" );
124134 goto deinit ;
125135 }
126- mcpwm_timer_event_callbacks_t cbs = {
127- .on_full = & read_adc_on_full ,
128- };
129- config -> six_step_config .upper_switch_config .bldc_mcpwm .cbs = & cbs ;
136+
137+ control -> cbs = malloc (sizeof (mcpwm_timer_event_callbacks_t ));
138+ if (!control -> cbs ) {
139+ ESP_LOGE (TAG , "malloc cbs failed" );
140+ goto deinit ;
141+ }
142+ memset (control -> cbs , 0 , sizeof (mcpwm_timer_event_callbacks_t ));
143+ control -> cbs -> on_full = & read_adc_on_full ;
144+ config -> six_step_config .upper_switch_config .bldc_mcpwm .cbs = control -> cbs ;
130145 config -> six_step_config .upper_switch_config .bldc_mcpwm .timer_cb_user_data = (void * )control -> zero_cross_handle ;
146+
131147 break ;
132148 }
133149#endif
@@ -155,7 +171,12 @@ esp_err_t bldc_control_init(bldc_control_handle_t *handle, bldc_control_config_t
155171 pid_ctrl_config_t pid_ctrl_config = {
156172 .init_param = PID_CTRL_PARAMETER_DEFAULT (),
157173 };
158- pid_new_control_block (& pid_ctrl_config , & control -> pid );
174+ ret = pid_new_control_block (& pid_ctrl_config , & control -> pid );
175+ if (ret != ESP_OK || control -> pid == NULL ) {
176+ ESP_LOGE (TAG , "pid_new_control_block failed: %d" , ret );
177+ ret = (ret != ESP_OK ) ? ret : ESP_FAIL ;
178+ goto deinit ;
179+ }
159180 }
160181
161182 control -> speed_mode = config -> speed_mode ;
@@ -164,6 +185,9 @@ esp_err_t bldc_control_init(bldc_control_handle_t *handle, bldc_control_config_t
164185
165186 return ESP_OK ;
166187deinit :
188+ if (control -> cbs ) {
189+ free (control -> cbs );
190+ }
167191 if (control -> change_phase_handle ) {
168192 // todo change_phase_deinit
169193 free (control -> change_phase_handle );
@@ -204,6 +228,10 @@ esp_err_t bldc_control_deinit(bldc_control_handle_t *handle)
204228 break ;
205229 }
206230
231+ if (control -> cbs ) {
232+ free (control -> cbs );
233+ control -> cbs = NULL ;
234+ }
207235 if (control -> xSemaphore ) {
208236 vSemaphoreDelete (control -> xSemaphore );
209237 }
@@ -218,6 +246,9 @@ esp_err_t bldc_control_deinit(bldc_control_handle_t *handle)
218246esp_err_t bldc_control_start (bldc_control_handle_t * handle , uint32_t expect_Speed_rpm )
219247{
220248 bldc_control_t * control = (bldc_control_t * )handle ;
249+ if (control -> is_running ) {
250+ return bldc_control_set_speed_rpm (handle , (int )expect_Speed_rpm );
251+ }
221252 switch (control -> control_mode ) {
222253 case BLDC_SIX_STEP :
223254 bldc_six_step_start (control -> change_phase_handle );
@@ -245,15 +276,27 @@ esp_err_t bldc_control_start(bldc_control_handle_t *handle, uint32_t expect_Spee
245276 control -> control_param .inject_count = 0 ;
246277 control -> control_param .adc_bemf_phase = 0 ;
247278
248- pid_reset_ctrl_block (control -> pid );
279+ if (control -> speed_mode == SPEED_CLOSED_LOOP ) {
280+ if (control -> pid == NULL ) {
281+ ESP_LOGE (TAG , "PID not initialized in CLOSED_LOOP mode" );
282+ return ESP_ERR_INVALID_STATE ;
283+ }
284+ pid_reset_ctrl_block (control -> pid );
285+ }
249286
250- bldc_control_dispatch_event ( BLDC_CONTROL_START , NULL , 0 );
287+ // Start timer then dispatch START event if success
251288#if INJECT_ENABLE
252289 control -> control_param .status = INJECT ;
253290#else
254291 control -> control_param .status = ALIGNMENT ;
255292#endif // INJECT_ENABLE
256- bldc_gptimer_start (control -> gptimer );
293+ esp_err_t err = bldc_gptimer_start (control -> gptimer );
294+ if (err != ESP_OK ) {
295+ ESP_LOGE (TAG , "bldc_gptimer_start failed: %d" , err );
296+ return err ;
297+ }
298+ control -> is_running = true;
299+ bldc_control_dispatch_event (BLDC_CONTROL_START , NULL , 0 );
257300
258301 return ESP_OK ;
259302}
@@ -284,6 +327,7 @@ esp_err_t bldc_control_stop(bldc_control_handle_t *handle)
284327 break ;
285328 }
286329
330+ control -> is_running = false;
287331 bldc_control_dispatch_event (BLDC_CONTROL_STOP , NULL , 0 );
288332 return ESP_OK ;
289333}
0 commit comments