diff --git a/applications/main/infrared/infrared.c b/applications/main/infrared/infrared.c index 4f450496..685dd57e 100644 --- a/applications/main/infrared/infrared.c +++ b/applications/main/infrared/infrared.c @@ -312,7 +312,8 @@ void infrared_tx_start_signal(Infrared* infrared, InfraredSignal* signal) { if(infrared_signal_is_raw(signal)) { InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal); - infrared_worker_set_raw_signal(infrared->worker, raw->timings, raw->timings_size); + infrared_worker_set_raw_signal( + infrared->worker, raw->timings, raw->timings_size, raw->frequency, raw->duty_cycle); } else { InfraredMessage* message = infrared_signal_get_message(signal); infrared_worker_set_decoded_signal(infrared->worker, message); diff --git a/firmware/targets/f18/api_symbols.csv b/firmware/targets/f18/api_symbols.csv index ee1ae115..b7abdfc0 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,+,26.3,, +Version,+,27.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index e2bedffb..15c19091 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,+,26.3,, +Version,+,27.0,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -1715,7 +1715,7 @@ Function,+,infrared_worker_rx_set_received_signal_callback,void,"InfraredWorker* Function,+,infrared_worker_rx_start,void,InfraredWorker* Function,+,infrared_worker_rx_stop,void,InfraredWorker* Function,+,infrared_worker_set_decoded_signal,void,"InfraredWorker*, const InfraredMessage*" -Function,+,infrared_worker_set_raw_signal,void,"InfraredWorker*, const uint32_t*, size_t" +Function,+,infrared_worker_set_raw_signal,void,"InfraredWorker*, const uint32_t*, size_t, uint32_t, float" Function,+,infrared_worker_signal_is_decoded,_Bool,const InfraredWorkerSignal* Function,+,infrared_worker_tx_get_signal_steady_callback,InfraredWorkerGetSignalResponse,"void*, InfraredWorker*" Function,+,infrared_worker_tx_set_get_signal_callback,void,"InfraredWorker*, InfraredWorkerGetSignalCallback, void*" diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index 2598e5fa..7b4f1708 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -1,7 +1,6 @@ #include #include #include "stm32wbxx_ll_dma.h" -#include "sys/_stdint.h" #include #include @@ -13,11 +12,10 @@ #include #include -#define INFRARED_TX_DEBUG 0 +// #define INFRARED_TX_DEBUG -#if INFRARED_TX_DEBUG == 1 -#define gpio_infrared_tx gpio_infrared_tx_debug -const GpioPin gpio_infrared_tx_debug = {.port = GPIOA, .pin = GpioModeAnalog}; +#if defined INFRARED_TX_DEBUG +#define gpio_infrared_tx gpio_ext_pa7 #endif #define INFRARED_TIM_TX_DMA_BUFFER_SIZE 200 @@ -330,8 +328,6 @@ static void furi_hal_infrared_tx_dma_isr() { } static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) { - /* LL_DBGMCU_APB2_GRP1_FreezePeriph(LL_DBGMCU_APB2_GRP1_TIM1_STOP); */ - LL_TIM_DisableCounter(TIM1); LL_TIM_SetRepetitionCounter(TIM1, 0); LL_TIM_SetCounter(TIM1, 0); @@ -340,7 +336,7 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc LL_TIM_EnableARRPreload(TIM1); LL_TIM_SetAutoReload( TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), freq)); -#if INFRARED_TX_DEBUG == 1 +#if defined INFRARED_TX_DEBUG LL_TIM_OC_SetCompareCH1(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle))); LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1); /* LL_TIM_OCMODE_PWM2 set by DMA */ @@ -370,7 +366,7 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { LL_DMA_InitTypeDef dma_config = {0}; -#if INFRARED_TX_DEBUG == 1 +#if defined INFRARED_TX_DEBUG dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1); #else dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR2); diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index 5add1413..46effd42 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -40,8 +40,12 @@ struct InfraredWorkerSignal { size_t timings_cnt; union { InfraredMessage message; - /* +1 is for pause we add at the beginning */ - uint32_t timings[MAX_TIMINGS_AMOUNT + 1]; + struct { + /* +1 is for pause we add at the beginning */ + uint32_t timings[MAX_TIMINGS_AMOUNT + 1]; + uint32_t frequency; + float duty_cycle; + } raw; }; }; @@ -146,7 +150,7 @@ static void } if(instance->signal.timings_cnt < MAX_TIMINGS_AMOUNT) { - instance->signal.timings[instance->signal.timings_cnt] = duration; + instance->signal.raw.timings[instance->signal.timings_cnt] = duration; ++instance->signal.timings_cnt; } else { uint32_t flags_set = furi_thread_flags_set( @@ -300,7 +304,7 @@ void infrared_worker_get_raw_signal( furi_assert(timings); furi_assert(timings_cnt); - *timings = signal->timings; + *timings = signal->raw.timings; *timings_cnt = signal->timings_cnt; } @@ -390,8 +394,8 @@ static bool infrared_get_new_signal(InfraredWorker* instance) { infrared_get_protocol_duty_cycle(instance->signal.message.protocol); } else { furi_assert(instance->signal.timings_cnt > 1); - new_tx_frequency = INFRARED_COMMON_CARRIER_FREQUENCY; - new_tx_duty_cycle = INFRARED_COMMON_DUTY_CYCLE; + new_tx_frequency = instance->signal.raw.frequency; + new_tx_duty_cycle = instance->signal.raw.duty_cycle; } instance->tx.tx_raw_cnt = 0; @@ -426,7 +430,7 @@ static bool infrared_worker_tx_fill_buffer(InfraredWorker* instance) { if(instance->signal.decoded) { status = infrared_encode(instance->infrared_encoder, &timing.duration, &timing.level); } else { - timing.duration = instance->signal.timings[instance->tx.tx_raw_cnt]; + timing.duration = instance->signal.raw.timings[instance->tx.tx_raw_cnt]; /* raw always starts from Mark, but we fill it with space delay at start */ timing.level = (instance->tx.tx_raw_cnt % 2); ++instance->tx.tx_raw_cnt; @@ -597,15 +601,21 @@ void infrared_worker_set_decoded_signal(InfraredWorker* instance, const Infrared void infrared_worker_set_raw_signal( InfraredWorker* instance, const uint32_t* timings, - size_t timings_cnt) { + size_t timings_cnt, + uint32_t frequency, + float duty_cycle) { furi_assert(instance); furi_assert(timings); furi_assert(timings_cnt > 0); - size_t max_copy_num = COUNT_OF(instance->signal.timings) - 1; + furi_assert((frequency <= INFRARED_MAX_FREQUENCY) && (frequency >= INFRARED_MIN_FREQUENCY)); + furi_assert((duty_cycle < 1.0f) && (duty_cycle > 0.0f)); + size_t max_copy_num = COUNT_OF(instance->signal.raw.timings) - 1; furi_check(timings_cnt <= max_copy_num); - instance->signal.timings[0] = INFRARED_RAW_TX_TIMING_DELAY_US; - memcpy(&instance->signal.timings[1], timings, timings_cnt * sizeof(uint32_t)); + instance->signal.raw.frequency = frequency; + instance->signal.raw.duty_cycle = duty_cycle; + instance->signal.raw.timings[0] = INFRARED_RAW_TX_TIMING_DELAY_US; + memcpy(&instance->signal.raw.timings[1], timings, timings_cnt * sizeof(uint32_t)); instance->signal.decoded = false; instance->signal.timings_cnt = timings_cnt + 1; } diff --git a/lib/infrared/worker/infrared_worker.h b/lib/infrared/worker/infrared_worker.h index 1a8cd9a7..e0e86198 100644 --- a/lib/infrared/worker/infrared_worker.h +++ b/lib/infrared/worker/infrared_worker.h @@ -130,9 +130,9 @@ void infrared_worker_tx_set_signal_sent_callback( /** Callback to pass to infrared_worker_tx_set_get_signal_callback() if signal * is steady and will not be changed between infrared_worker start and stop. * Before starting transmission, desired steady signal must be set with - * infrared_worker_make_decoded_signal() or infrared_worker_make_raw_signal(). + * infrared_worker_set_decoded_signal() or infrared_worker_set_raw_signal(). * - * This function should not be implicitly called. + * This function should not be called directly. * * @param[in] context - context * @param[out] instance - InfraredWorker instance @@ -172,11 +172,15 @@ void infrared_worker_set_decoded_signal(InfraredWorker* instance, const Infrared * @param[out] instance - InfraredWorker instance * @param[in] timings - array of raw timings * @param[in] timings_cnt - size of array of raw timings + * @param[in] frequency - carrier frequency in Hertz + * @param[in] duty_cycle - carrier duty cycle (0.0 - 1.0) */ void infrared_worker_set_raw_signal( InfraredWorker* instance, const uint32_t* timings, - size_t timings_cnt); + size_t timings_cnt, + uint32_t frequency, + float duty_cycle); #ifdef __cplusplus }