IR-protocol/IR_Encoder.h
2024-12-25 16:56:18 +03:00

118 lines
3.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "IR_config.h"
// TODO: Отложенная передача после завершения приема
class IR_DecoderRaw;
class IR_Encoder : public IR_FOX
{
friend IR_DecoderRaw;
public:
private:
// uint16_t id; /// @brief Адрес передатчика
public:
/// @brief Класс передатчика
/// @param addr Адрес передатчика
/// @param pin Вывод передатчика
/// @param tune Подстройка несущей частоты
/// @param decPair Приёмник, для которого отключается приём в момент передачи передатчиком
IR_Encoder(uint16_t addr, IR_DecoderRaw *decPair = nullptr);
static void timerSetup()
{
// TIMER2 Ini
uint8_t oldSREG = SREG; // Save global interupts settings
cli();
// DDRB |= (1 << PORTB3); //OC2A (17)
TCCR2A = 0;
TCCR2B = 0;
// TCCR2A |= (1 << COM2A0); //Переключение состояния
TCCR2A |= (1 << WGM21); // Clear Timer On Compare (Сброс по совпадению)
TCCR2B |= (1 << CS20); // Предделитель 1
TIMSK2 |= (1 << OCIE2A); // Прерывание по совпадению
OCR2A = /* 465 */ ((F_CPU / (38000 * 2)) - 2); // 38кГц
SREG = oldSREG; // Return interrupt settings
}
static void timerOFFSetup()
{
TIMSK2 &= ~(1 << OCIE2A); // Прерывание по совпадению выкл
}
void IR_Encoder::setBlindDecoders(IR_DecoderRaw *decoders[], uint8_t count);
void rawSend(uint8_t *ptr, uint8_t len);
void sendData(uint16_t addrTo, uint8_t dataByte, bool needAccept = false);
void sendData(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false);
void sendData(uint16_t addrFrom, uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0, bool needAccept = false);
void sendAccept(uint16_t addrTo, uint8_t customByte = 0);
void sendRequest(uint16_t addrTo);
void sendBack(uint8_t data);
void sendBack(uint8_t *data = nullptr, uint8_t len = 0);
void sendBackTo(uint16_t addrTo, uint8_t *data = nullptr, uint8_t len = 0);
void isr();
~IR_Encoder();
volatile bool ir_out_virtual;
private:
void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t *data, uint8_t len);
void IR_Encoder::setDecoder_isSending();
void sendByte(uint8_t byte, bool *prev, bool LOW_FIRST);
void addSync(bool *prev, bool *next);
void send_HIGH(bool = 1);
void send_LOW();
void send_EMPTY(uint8_t count);
enum SignalPart : uint8_t
{
noSignal = 0,
preamb = 1,
data = 2,
sync = 3
};
IR_DecoderRaw *decPair;
IR_DecoderRaw **blindDecoders;
uint8_t decodersCount;
uint8_t sendLen;
uint8_t sendBuffer[dataByteSizeMax]{0}; /// @brief Буффер данных для отправки
volatile bool isSending;
volatile bool state; /// @brief Текущий уровень генерации
volatile uint8_t dataByteCounter;
volatile uint8_t toggleCounter; /// @brief Счётчик переключений
volatile uint8_t dataBitCounter;
volatile uint8_t preambFrontCounter;
volatile uint8_t dataSequenceCounter;
volatile uint8_t syncSequenceCounter;
volatile bool syncLastBit;
struct BitSequence
{
uint8_t low;
uint8_t high;
};
static inline uint8_t *bitHigh = new uint8_t[2]{
(bitPauseTakts * 2) * 2 - 1,
(bitActiveTakts) * 2 - 1};
static inline uint8_t *bitLow = new uint8_t[2]{
(bitPauseTakts + bitActiveTakts) * 2 - 1,
(bitPauseTakts) * 2 - 1};
uint8_t *currentBitSequence = bitLow;
volatile SignalPart signal;
};