flipperzero-firmware/lib/irda/irda_transmit.c

67 lines
1.7 KiB
C
Raw Normal View History

#include "irda.h"
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <furi.h>
#include <api-hal-irda.h>
#include <api-hal-delay.h>
static void irda_set_tx(uint32_t duration, bool level) {
if (level) {
api_hal_irda_pwm_set(IRDA_COMMON_DUTY_CYCLE, IRDA_COMMON_CARRIER_FREQUENCY);
delay_us(duration);
} else {
api_hal_irda_pwm_stop();
delay_us(duration);
}
}
void irda_send_raw(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark) {
__disable_irq();
for (uint32_t i = 0; i < timings_cnt; ++i) {
irda_set_tx(timings[i], (i % 2) ^ start_from_mark);
}
irda_set_tx(0, false);
__enable_irq();
}
void irda_send(const IrdaMessage* message, int times) {
furi_assert(message);
furi_assert(irda_is_protocol_valid(message->protocol));
IrdaStatus status;
uint32_t duration = 0;
bool level = false;
IrdaEncoderHandler* handler = irda_alloc_encoder();
irda_reset_encoder(handler, message);
/* Hotfix: first timings is space timing, so make delay instead of locking
* whole system for that long. Replace when async timing lib will be ready.
* This timing doesn't have to be precise.
*/
status = irda_encode(handler, &duration, &level);
furi_assert(status != IrdaStatusError);
furi_assert(level == false);
delay_us(duration);
__disable_irq();
while (times) {
status = irda_encode(handler, &duration, &level);
if (status != IrdaStatusError) {
irda_set_tx(duration, level);
} else {
furi_assert(0);
break;
}
if (status == IrdaStatusDone)
--times;
}
irda_set_tx(0, false);
__enable_irq();
irda_free_encoder(handler);
}