flipperzero-firmware/lib/irda/worker/irda_transmit.c

102 lines
3.4 KiB
C
Raw Normal View History

#include "irda.h"
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <furi.h>
2021-08-08 18:03:25 +00:00
#include <furi-hal-irda.h>
#include <furi-hal-delay.h>
2021-08-05 21:11:35 +00:00
static uint32_t irda_tx_number_of_transmissions = 0;
static uint32_t irda_tx_raw_timings_index = 0;
static uint32_t irda_tx_raw_timings_number = 0;
static uint32_t irda_tx_raw_start_from_mark = 0;
static bool irda_tx_raw_add_silence = false;
2021-08-08 18:03:25 +00:00
FuriHalIrdaTxGetDataState irda_get_raw_data_callback (void* context, uint32_t* duration, bool* level) {
2021-08-05 21:11:35 +00:00
furi_assert(duration);
furi_assert(level);
furi_assert(context);
2021-08-08 18:03:25 +00:00
FuriHalIrdaTxGetDataState state = FuriHalIrdaTxGetDataStateOk;
2021-08-05 21:11:35 +00:00
const uint32_t* timings = context;
if (irda_tx_raw_add_silence && (irda_tx_raw_timings_index == 0)) {
irda_tx_raw_add_silence = false;
*level = false;
*duration = IRDA_RAW_TX_TIMING_DELAY_US;
} else {
2021-08-05 21:11:35 +00:00
*level = irda_tx_raw_start_from_mark ^ (irda_tx_raw_timings_index % 2);
*duration = timings[irda_tx_raw_timings_index++];
}
2021-08-05 21:11:35 +00:00
if (irda_tx_raw_timings_number == irda_tx_raw_timings_index) {
2021-08-08 18:03:25 +00:00
state = FuriHalIrdaTxGetDataStateLastDone;
}
2021-08-05 21:11:35 +00:00
return state;
}
void irda_send_raw_ext(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark, uint32_t frequency, float duty_cycle) {
furi_assert(timings);
furi_assert(timings_cnt > 1);
irda_tx_raw_start_from_mark = start_from_mark;
irda_tx_raw_timings_index = 0;
irda_tx_raw_timings_number = timings_cnt;
irda_tx_raw_add_silence = start_from_mark;
2021-08-08 18:03:25 +00:00
furi_hal_irda_async_tx_set_data_isr_callback(irda_get_raw_data_callback, (void*) timings);
furi_hal_irda_async_tx_start(frequency, duty_cycle);
furi_hal_irda_async_tx_wait_termination();
2021-08-05 21:11:35 +00:00
2021-08-08 18:03:25 +00:00
furi_assert(!furi_hal_irda_is_busy());
}
void irda_send_raw(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark) {
2021-08-05 21:11:35 +00:00
irda_send_raw_ext(timings, timings_cnt, start_from_mark, IRDA_COMMON_CARRIER_FREQUENCY, IRDA_COMMON_DUTY_CYCLE);
}
2021-08-08 18:03:25 +00:00
FuriHalIrdaTxGetDataState irda_get_data_callback (void* context, uint32_t* duration, bool* level) {
FuriHalIrdaTxGetDataState state = FuriHalIrdaTxGetDataStateError;
2021-08-05 21:11:35 +00:00
IrdaEncoderHandler* handler = context;
IrdaStatus status = IrdaStatusError;
if (irda_tx_number_of_transmissions > 0) {
status = irda_encode(handler, duration, level);
}
if (status == IrdaStatusError) {
2021-08-08 18:03:25 +00:00
state = FuriHalIrdaTxGetDataStateError;
2021-08-05 21:11:35 +00:00
} else if (status == IrdaStatusOk) {
2021-08-08 18:03:25 +00:00
state = FuriHalIrdaTxGetDataStateOk;
2021-08-05 21:11:35 +00:00
} else if (status == IrdaStatusDone) {
2021-08-08 18:03:25 +00:00
state = FuriHalIrdaTxGetDataStateDone;
2021-08-05 21:11:35 +00:00
if (--irda_tx_number_of_transmissions == 0) {
2021-08-08 18:03:25 +00:00
state = FuriHalIrdaTxGetDataStateLastDone;
2021-08-05 21:11:35 +00:00
}
} else {
furi_assert(0);
2021-08-08 18:03:25 +00:00
state = FuriHalIrdaTxGetDataStateError;
}
2021-08-05 21:11:35 +00:00
return state;
}
void irda_send(const IrdaMessage* message, int times) {
furi_assert(message);
2021-08-05 21:11:35 +00:00
furi_assert(times);
furi_assert(irda_is_protocol_valid(message->protocol));
IrdaEncoderHandler* handler = irda_alloc_encoder();
irda_reset_encoder(handler, message);
2021-08-05 21:11:35 +00:00
irda_tx_number_of_transmissions = times;
2021-08-08 18:03:25 +00:00
furi_hal_irda_async_tx_set_data_isr_callback(irda_get_data_callback, handler);
furi_hal_irda_async_tx_start(IRDA_COMMON_CARRIER_FREQUENCY, IRDA_COMMON_DUTY_CYCLE);
furi_hal_irda_async_tx_wait_termination();
irda_free_encoder(handler);
2021-08-05 21:11:35 +00:00
2021-08-08 18:03:25 +00:00
furi_assert(!furi_hal_irda_is_busy());
}