Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FL-3322] Infrared: respect carrier frequency and duty cycle settings #2677

Merged
merged 3 commits into from
May 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion applications/main/infrared/infrared.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion firmware/targets/f18/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -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,,
Expand Down
4 changes: 2 additions & 2 deletions firmware/targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -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,,
Expand Down Expand Up @@ -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*"
Expand Down
14 changes: 5 additions & 9 deletions firmware/targets/f7/furi_hal/furi_hal_infrared.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <furi_hal_infrared.h>
#include <core/check.h>
#include "stm32wbxx_ll_dma.h"
#include "sys/_stdint.h"
#include <furi_hal_interrupt.h>
#include <furi_hal_resources.h>

Expand All @@ -13,11 +12,10 @@
#include <furi.h>
#include <math.h>

#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
Expand Down Expand Up @@ -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);
Expand All @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
32 changes: 21 additions & 11 deletions lib/infrared/worker/infrared_worker.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
};

Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 7 additions & 3 deletions lib/infrared/worker/infrared_worker.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
}
Expand Down