mirror of
https://github.com/Show-maket/IR-protocol.git
synced 2025-05-03 06:40:16 +00:00
118 lines
3.8 KiB
C++
118 lines
3.8 KiB
C++
#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;
|
||
};
|