diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c index 0ee5cefa1..b4c12cbc3 100644 --- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c +++ b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c @@ -60,7 +60,9 @@ static int32_t avr_isp_worker_rw_thread(void* context) { AvrIspWorkerRW* instance = context; /* start PWM on &gpio_ext_pa4 */ - furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50); + if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) { + furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50); + } FURI_LOG_D(TAG, "Start"); @@ -122,7 +124,9 @@ static int32_t avr_isp_worker_rw_thread(void* context) { } FURI_LOG_D(TAG, "Stop"); - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) { + furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + } return 0; } @@ -136,7 +140,12 @@ bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) { instance->chip_arr_ind = avr_isp_chip_arr_size + 1; /* start PWM on &gpio_ext_pa4 */ - furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50); + bool was_pwm_enabled = false; + if(!furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4)) { + furi_hal_pwm_start(FuriHalPwmOutputIdLptim2PA4, 4000000, 50); + } else { + was_pwm_enabled = true; + } do { if(!avr_isp_auto_set_spi_speed_start_pmode(instance->avr_isp)) { @@ -200,7 +209,9 @@ bool avr_isp_worker_rw_detect_chip(AvrIspWorkerRW* instance) { } while(0); - furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + if(furi_hal_pwm_is_running(FuriHalPwmOutputIdLptim2PA4) && !was_pwm_enabled) { + furi_hal_pwm_stop(FuriHalPwmOutputIdLptim2PA4); + } if(instance->callback) { if(instance->chip_arr_ind > avr_isp_chip_arr_size) { diff --git a/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c b/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c index 7ac3fadda..1cadb3a1a 100644 --- a/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c +++ b/applications/external/signal_generator/scenes/signal_gen_scene_pwm.c @@ -33,7 +33,13 @@ void signal_gen_scene_pwm_on_enter(void* context) { signal_gen_pwm_set_callback(app->pwm_view, signal_gen_pwm_callback, app); signal_gen_pwm_set_params(app->pwm_view, 0, DEFAULT_FREQ, DEFAULT_DUTY); - furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); + + if(!furi_hal_pwm_is_running(pwm_ch_id[0])) { + furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); + } else { + furi_hal_pwm_stop(pwm_ch_id[0]); + furi_hal_pwm_start(pwm_ch_id[0], DEFAULT_FREQ, DEFAULT_DUTY); + } } bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) { @@ -46,8 +52,18 @@ bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) { furi_hal_pwm_set_params(app->pwm_ch, app->pwm_freq, app->pwm_duty); } else if(event.event == SignalGenPwmEventChannelChange) { consumed = true; - furi_hal_pwm_stop(app->pwm_ch_prev); - furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); + // Stop previous channel PWM + if(furi_hal_pwm_is_running(app->pwm_ch_prev)) { + furi_hal_pwm_stop(app->pwm_ch_prev); + } + + // Start PWM and restart if it was starter already + if(furi_hal_pwm_is_running(app->pwm_ch)) { + furi_hal_pwm_stop(app->pwm_ch); + furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); + } else { + furi_hal_pwm_start(app->pwm_ch, app->pwm_freq, app->pwm_duty); + } } } return consumed; @@ -56,5 +72,8 @@ bool signal_gen_scene_pwm_on_event(void* context, SceneManagerEvent event) { void signal_gen_scene_pwm_on_exit(void* context) { SignalGenApp* app = context; variable_item_list_reset(app->var_item_list); - furi_hal_pwm_stop(app->pwm_ch); + + if(furi_hal_pwm_is_running(app->pwm_ch)) { + furi_hal_pwm_stop(app->pwm_ch); + } } diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index 0b4e2d6d6..2e176a5b5 100644 --- a/firmware/targets/f18/api_symbols.csv +++ b/firmware/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,31.1,, +Version,+,31.2,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1061,6 +1061,7 @@ Function,+,furi_hal_power_sleep,void, Function,+,furi_hal_power_sleep_available,_Bool, Function,+,furi_hal_power_suppress_charge_enter,void, Function,+,furi_hal_power_suppress_charge_exit,void, +Function,+,furi_hal_pwm_is_running,_Bool,FuriHalPwmOutputId Function,+,furi_hal_pwm_set_params,void,"FuriHalPwmOutputId, uint32_t, uint8_t" Function,+,furi_hal_pwm_start,void,"FuriHalPwmOutputId, uint32_t, uint8_t" Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 5ba66407e..ac2b11f38 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,31.1,, +Version,+,31.2,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1286,6 +1286,7 @@ Function,+,furi_hal_power_sleep,void, Function,+,furi_hal_power_sleep_available,_Bool, Function,+,furi_hal_power_suppress_charge_enter,void, Function,+,furi_hal_power_suppress_charge_exit,void, +Function,+,furi_hal_pwm_is_running,_Bool,FuriHalPwmOutputId Function,+,furi_hal_pwm_set_params,void,"FuriHalPwmOutputId, uint32_t, uint8_t" Function,+,furi_hal_pwm_start,void,"FuriHalPwmOutputId, uint32_t, uint8_t" Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId diff --git a/firmware/targets/f7/furi_hal/furi_hal_pwm.c b/firmware/targets/f7/furi_hal/furi_hal_pwm.c index 7e985cbb1..879460e6b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_pwm.c +++ b/firmware/targets/f7/furi_hal/furi_hal_pwm.c @@ -82,6 +82,15 @@ void furi_hal_pwm_stop(FuriHalPwmOutputId channel) { } } +bool furi_hal_pwm_is_running(FuriHalPwmOutputId channel) { + if(channel == FuriHalPwmOutputIdTim1PA7) { + return furi_hal_bus_is_enabled(FuriHalBusTIM1); + } else if(channel == FuriHalPwmOutputIdLptim2PA4) { + return furi_hal_bus_is_enabled(FuriHalBusLPTIM2); + } + return false; +} + void furi_hal_pwm_set_params(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty) { furi_assert(freq > 0); uint32_t freq_div = 64000000LU / freq; diff --git a/firmware/targets/f7/furi_hal/furi_hal_pwm.h b/firmware/targets/f7/furi_hal/furi_hal_pwm.h index a8682c5fb..16acca05e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_pwm.h +++ b/firmware/targets/f7/furi_hal/furi_hal_pwm.h @@ -9,6 +9,7 @@ extern "C" { #endif #include +#include typedef enum { FuriHalPwmOutputIdTim1PA7, @@ -37,6 +38,13 @@ void furi_hal_pwm_stop(FuriHalPwmOutputId channel); */ void furi_hal_pwm_set_params(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty); +/** Is PWM channel running? + * + * @param[in] channel PWM channel (FuriHalPwmOutputId) + * @return bool - true if running +*/ +bool furi_hal_pwm_is_running(FuriHalPwmOutputId channel); + #ifdef __cplusplus } #endif