[FL-3078] Per protocol signal repeat count (#2293)
* Better Infrared protocol file structure * Rename InfraredProtocolSpec to InfraredProtocolVariant * Slightly better names * Add repeat count field to protocol variant description * Repeat the signal the appropriate number of times when brute-forcing * Repeat the signal the appropriate number of times when sending via worker * Better signal count logic in infrared_transmit * Better variable names * Convert some raw signals to messages in tv.ir Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -101,7 +101,8 @@ void infrared_send(const InfraredMessage* message, int times) {
|
||||
|
||||
InfraredEncoderHandler* handler = infrared_alloc_encoder();
|
||||
infrared_reset_encoder(handler, message);
|
||||
infrared_tx_number_of_transmissions = times;
|
||||
infrared_tx_number_of_transmissions =
|
||||
MAX((int)infrared_get_protocol_min_repeat_count(message->protocol), times);
|
||||
|
||||
uint32_t frequency = infrared_get_protocol_frequency(message->protocol);
|
||||
float duty_cycle = infrared_get_protocol_duty_cycle(message->protocol);
|
||||
|
@@ -1,13 +1,10 @@
|
||||
#include "infrared_worker.h"
|
||||
|
||||
#include <furi_hal_infrared.h>
|
||||
#include <float_tools.h>
|
||||
|
||||
#include <core/check.h>
|
||||
#include <core/common_defines.h>
|
||||
#include "sys/_stdint.h"
|
||||
#include "infrared_worker.h"
|
||||
#include <infrared.h>
|
||||
#include <furi_hal_infrared.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <furi.h>
|
||||
#include <float_tools.h>
|
||||
|
||||
#include <notification/notification_messages.h>
|
||||
|
||||
@@ -471,18 +468,23 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
||||
furi_assert(instance->state == InfraredWorkerStateStartTx);
|
||||
furi_assert(thread_context);
|
||||
|
||||
size_t repeats_left =
|
||||
instance->signal.decoded ?
|
||||
infrared_get_protocol_min_repeat_count(instance->signal.message.protocol) :
|
||||
1;
|
||||
uint32_t events = 0;
|
||||
bool new_data_available = true;
|
||||
bool exit = false;
|
||||
|
||||
exit = !infrared_get_new_signal(instance);
|
||||
furi_assert(!exit);
|
||||
bool exit_pending = false;
|
||||
|
||||
while(!exit) {
|
||||
bool running = infrared_get_new_signal(instance);
|
||||
furi_assert(running);
|
||||
|
||||
while(running) {
|
||||
switch(instance->state) {
|
||||
case InfraredWorkerStateStartTx:
|
||||
--repeats_left; /* The first message does not result in TX_MESSAGE_SENT event for some reason */
|
||||
instance->tx.need_reinitialization = false;
|
||||
new_data_available = infrared_worker_tx_fill_buffer(instance);
|
||||
const bool new_data_available = infrared_worker_tx_fill_buffer(instance);
|
||||
furi_hal_infrared_async_tx_start(instance->tx.frequency, instance->tx.duty_cycle);
|
||||
|
||||
if(!new_data_available) {
|
||||
@@ -496,7 +498,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
||||
break;
|
||||
case InfraredWorkerStateStopTx:
|
||||
furi_hal_infrared_async_tx_stop();
|
||||
exit = true;
|
||||
running = false;
|
||||
break;
|
||||
case InfraredWorkerStateWaitTxEnd:
|
||||
furi_hal_infrared_async_tx_wait_termination();
|
||||
@@ -504,18 +506,18 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
||||
|
||||
events = furi_thread_flags_get();
|
||||
if(events & INFRARED_WORKER_EXIT) {
|
||||
exit = true;
|
||||
running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case InfraredWorkerStateRunTx:
|
||||
events = furi_thread_flags_wait(INFRARED_WORKER_ALL_TX_EVENTS, 0, FuriWaitForever);
|
||||
events = furi_thread_flags_wait(
|
||||
INFRARED_WORKER_ALL_TX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
|
||||
furi_check(events & INFRARED_WORKER_ALL_TX_EVENTS); /* at least one caught */
|
||||
|
||||
if(events & INFRARED_WORKER_EXIT) {
|
||||
instance->state = InfraredWorkerStateStopTx;
|
||||
break;
|
||||
exit_pending = true;
|
||||
}
|
||||
|
||||
if(events & INFRARED_WORKER_TX_FILL_BUFFER) {
|
||||
@@ -527,9 +529,19 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
||||
}
|
||||
|
||||
if(events & INFRARED_WORKER_TX_MESSAGE_SENT) {
|
||||
if(instance->tx.message_sent_callback)
|
||||
if(repeats_left > 0) {
|
||||
--repeats_left;
|
||||
}
|
||||
|
||||
if(instance->tx.message_sent_callback) {
|
||||
instance->tx.message_sent_callback(instance->tx.message_sent_context);
|
||||
}
|
||||
}
|
||||
|
||||
if(exit_pending && repeats_left == 0) {
|
||||
instance->state = InfraredWorkerStateStopTx;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
furi_assert(0);
|
||||
|
Reference in New Issue
Block a user