| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- #include "infrared.h"
- #include <stdint.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <furi.h>
- #include <furi_hal_infrared.h>
- static uint32_t infrared_tx_number_of_transmissions = 0;
- static uint32_t infrared_tx_raw_timings_index = 0;
- static uint32_t infrared_tx_raw_timings_number = 0;
- static uint32_t infrared_tx_raw_start_from_mark = 0;
- static bool infrared_tx_raw_add_silence = false;
- FuriHalInfraredTxGetDataState
- infrared_get_raw_data_callback(void* context, uint32_t* duration, bool* level) {
- furi_assert(duration);
- furi_assert(level);
- furi_assert(context);
- FuriHalInfraredTxGetDataState state = FuriHalInfraredTxGetDataStateOk;
- const uint32_t* timings = context;
- if(infrared_tx_raw_add_silence && (infrared_tx_raw_timings_index == 0)) {
- infrared_tx_raw_add_silence = false;
- *level = false;
- *duration = INFRARED_RAW_TX_TIMING_DELAY_US;
- } else {
- *level = infrared_tx_raw_start_from_mark ^ (infrared_tx_raw_timings_index % 2);
- *duration = timings[infrared_tx_raw_timings_index++];
- }
- if(infrared_tx_raw_timings_number == infrared_tx_raw_timings_index) {
- state = FuriHalInfraredTxGetDataStateLastDone;
- }
- return state;
- }
- void infrared_send_raw_ext(
- const uint32_t timings[],
- uint32_t timings_cnt,
- bool start_from_mark,
- uint32_t frequency,
- float duty_cycle) {
- furi_assert(timings);
- infrared_tx_raw_start_from_mark = start_from_mark;
- infrared_tx_raw_timings_index = 0;
- infrared_tx_raw_timings_number = timings_cnt;
- infrared_tx_raw_add_silence = start_from_mark;
- furi_hal_infrared_async_tx_set_data_isr_callback(
- infrared_get_raw_data_callback, (void*)timings);
- furi_hal_infrared_async_tx_start(frequency, duty_cycle);
- furi_hal_infrared_async_tx_wait_termination();
- furi_assert(!furi_hal_infrared_is_busy());
- }
- void infrared_send_raw(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark) {
- infrared_send_raw_ext(
- timings,
- timings_cnt,
- start_from_mark,
- INFRARED_COMMON_CARRIER_FREQUENCY,
- INFRARED_COMMON_DUTY_CYCLE);
- }
- FuriHalInfraredTxGetDataState
- infrared_get_data_callback(void* context, uint32_t* duration, bool* level) {
- FuriHalInfraredTxGetDataState state = FuriHalInfraredTxGetDataStateLastDone;
- InfraredEncoderHandler* handler = context;
- InfraredStatus status = InfraredStatusError;
- if(infrared_tx_number_of_transmissions > 0) {
- status = infrared_encode(handler, duration, level);
- }
- if(status == InfraredStatusError) {
- state = FuriHalInfraredTxGetDataStateLastDone;
- *duration = 0;
- *level = 0;
- } else if(status == InfraredStatusOk) {
- state = FuriHalInfraredTxGetDataStateOk;
- } else if(status == InfraredStatusDone) {
- state = FuriHalInfraredTxGetDataStateDone;
- if(--infrared_tx_number_of_transmissions == 0) {
- state = FuriHalInfraredTxGetDataStateLastDone;
- }
- } else {
- furi_crash(NULL);
- }
- return state;
- }
- void infrared_send(const InfraredMessage* message, int times) {
- furi_assert(message);
- furi_assert(times);
- furi_assert(infrared_is_protocol_valid(message->protocol));
- InfraredEncoderHandler* handler = infrared_alloc_encoder();
- infrared_reset_encoder(handler, message);
- infrared_tx_number_of_transmissions = times;
- uint32_t frequency = infrared_get_protocol_frequency(message->protocol);
- float duty_cycle = infrared_get_protocol_duty_cycle(message->protocol);
- furi_hal_infrared_async_tx_set_data_isr_callback(infrared_get_data_callback, handler);
- furi_hal_infrared_async_tx_start(frequency, duty_cycle);
- furi_hal_infrared_async_tx_wait_termination();
- infrared_free_encoder(handler);
- furi_assert(!furi_hal_infrared_is_busy());
- }
|