From e0fbc8502ddc69f8deb20279485fd7d50da49e29 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Tue, 6 Feb 2024 17:14:59 +0300 Subject: [PATCH] MultiGen isr --- IR_Encoder.cpp | 149 +++++++++++++++++++++++++++++++++++-------------- IR_Encoder.h | 53 ++++++++++++------ IR_config.h | 6 +- 3 files changed, 148 insertions(+), 60 deletions(-) diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index cad54f2..dd7291d 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -3,12 +3,18 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) { ir_out = pin; + pinMode(ir_out, OUTPUT); addrSelf = addr; decoder = decPair; carrierTune = tune; halfPeriod = (carrierPeriod / 2) - carrierTune; + dataBitCounter = 0 - preambFronts; + signal = noSignal; }; + + + IR_Encoder::~IR_Encoder() {}; void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { @@ -102,34 +108,105 @@ void IR_Encoder::_sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t } void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { - /*tmp*/bool LOW_FIRST = false;/*tmp*/ + digitalToggle(9); digitalToggle(9); + isSending = true; + if (decoder != nullptr) { decoder->isPairSending = isSending; } + cli(); + // toggleCounter = bitTakts*2 - 1; + #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) + // #define preambToggle (3*2-1) + toggleCounter = preambToggle; + preambBitCounter = preambPulse; + dataBitCounter = 0; + syncBitCounter = 0; - if (decoder != nullptr) { decoder->isPairSending = true; } + signal = preamb; + isSending = true; + state = HIGH; + sei(); +} - bool prev = 1; - bool next; - send_EMPTY(preambPulse); // преамбула - for (uint16_t byteNum = 0; byteNum < len; byteNum++) { - sendByte(ptr[byteNum], &prev, LOW_FIRST); - if (byteNum < len - 1) { - next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000); - } else { - next = 0; +void IR_Encoder::isr() { + if (!isSending) return; + + ir_out_virtual = !ir_out_virtual && state; + + + if (!toggleCounter) { + + state = !state; + + switch (signal) { + case noSignal: + return; + break; + + case preamb: + toggleCounter = preambToggle; + if (!state) { // Низкий уровень - конец периода генерации + preambBitCounter--; + if (!preambBitCounter) { // Конец преамбулы, переход на следующий этап + isSending = false; + } + } + break; + + case data: + signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + break; + + case sync: + signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + break; + + default: + return; + break; } - addSync(&prev, &next); - } - if (decoder != nullptr) { decoder->isPairSending = false; } + } else { toggleCounter--; } +} + + + + +void old() {/////////////////////////////////////////////////////// + // void IR_Encoder::rawSend(uint8_t* ptr, uint8_t len) { + // /*tmp*/bool LOW_FIRST = false;/*tmp*/ + + // if (decoder != nullptr) { decoder->isPairSending = true; } + + // bool prev = 1; + // bool next; + + // send_EMPTY(preambPulse); // преамбула + // for (uint16_t byteNum = 0; byteNum < len; byteNum++) { + // sendByte(ptr[byteNum], &prev, LOW_FIRST); + // if (byteNum < len - 1) { + // next = ptr[byteNum + 1] & (LOW_FIRST ? 0b00000001 : 0b10000000); + // } else { + // next = 0; + // } + // addSync(&prev, &next); + // } + + // if (decoder != nullptr) { decoder->isPairSending = false; } + + // } } void IR_Encoder::sendByte(uint8_t byte, bool* prev, bool LOW_FIRST) { uint8_t mask = LOW_FIRST ? 0b00000001 : 0b10000000; for (uint8_t bitShift = 8; bitShift; bitShift--) { + digitalWrite(9, HIGH); + digitalWrite(9, LOW); byte& mask ? send_HIGH(prev) : send_LOW(); *prev = byte & mask; LOW_FIRST ? mask <<= 1 : mask >>= 1; + digitalWrite(9, HIGH); + digitalWrite(9, LOW); } } @@ -152,39 +229,29 @@ void IR_Encoder::addSync(bool* prev, bool* next) { } void IR_Encoder::send_HIGH(bool prevBite = 1) { - if (prevBite) { - meanderBlock(bitPauseTakts * 2, halfPeriod, LOW); - meanderBlock(bitActiveTakts, halfPeriod, HIGH); - } else { // более короткий HIGH после нуля - meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW); - meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH); - } + + // if (/* prevBite */1) { + // meanderBlock(bitPauseTakts * 2, halfPeriod, LOW); + // meanderBlock(bitActiveTakts, halfPeriod, HIGH); + // } else { // более короткий HIGH после нуля + // meanderBlock(bitTakts - (bitActiveTakts - bitPauseTakts), halfPeriod, LOW); + // meanderBlock(bitActiveTakts - bitPauseTakts, halfPeriod, HIGH); + // } + } void IR_Encoder::send_LOW() { - meanderBlock(bitPauseTakts, halfPeriod, LOW); - meanderBlock(bitActiveTakts, halfPeriod, LOW); - meanderBlock(bitPauseTakts, halfPeriod, HIGH); + // meanderBlock(bitPauseTakts, halfPeriod, LOW); + // meanderBlock(bitActiveTakts, halfPeriod, LOW); + // meanderBlock(bitPauseTakts, halfPeriod, HIGH); } void IR_Encoder::send_EMPTY(uint8_t count) { - for (size_t i = 0; i < count * 2; i++) { - meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, prevPreambBit); - prevPreambBit = !prevPreambBit; - } + // for (size_t i = 0; i < count * 2; i++) { + // meanderBlock((bitPauseTakts * 2 + bitActiveTakts), halfPeriod, prevPreambBit); + // prevPreambBit = !prevPreambBit; + // } + // meanderBlock(bitPauseTakts * 2 + bitActiveTakts, halfPeriod, 0); //TODO: Отодвинуть преамбулу } -void IR_Encoder::meanderBlock(uint16_t count, uint16_t _period, bool high = true) { - for (uint16_t i = 0; i < count << 1; i++) { - if ((i & 1)) { // Если чётное - //PORTC &= ~(1 << 3); // LOW - digitalWrite(ir_out, high ? LOW : LOW); - } else { // Если не четное - //PORTC |= 1 << 3; // HIGH - digitalWrite(ir_out, high ? HIGH : LOW); - } - - delayMicroseconds(_period); - } -} \ No newline at end of file diff --git a/IR_Encoder.h b/IR_Encoder.h index 42ec69b..3cf5569 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -6,22 +6,16 @@ class IR_Decoder; class IR_Encoder : IR_FOX { friend IR_Decoder; + friend void isr(IR_Encoder& e); public: - /// @brief Вывод передатчика - uint8_t ir_out; - /// @brief Адрес передатчика - uint16_t addrSelf; + uint8_t ir_out; /// @brief Вывод передатчика + uint16_t addrSelf; /// @brief Адрес передатчика private: - /// @brief предыдущий бит преамбулы - bool prevPreambBit = true; + uint8_t carrierTune; /// @brief Подстройка несущей частоты + uint8_t halfPeriod; /// @brief полупериод несущей частоты - /// @brief Подстройка несущей частоты - uint8_t carrierTune; - - /// @brief полупериод несущей частоты - uint8_t halfPeriod; public: /// @brief Класс передатчика @@ -35,23 +29,50 @@ public: void sendData(uint16_t addrTo, T& data, bool needAccept = false); void sendACK(uint16_t addrTo, uint8_t addInfo = 0, bool forAll = false); void sendRequest(uint16_t addrTo, uint8_t addInfo = 0); - + void rawSend(uint8_t* ptr, uint8_t len); + void isr(); ~IR_Encoder(); + volatile bool ir_out_virtual; private: IR_Decoder* decoder; - void meanderBlock(uint16_t count, uint16_t _period, bool isNoPause = true); + void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); 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); - void rawSend(uint8_t* ptr, uint8_t len); - void _sendData(uint16_t addrTo, uint8_t* data, uint8_t len, uint8_t msgType); + + enum SignalPart : uint8_t { + noSignal = 0, + preamb = 1, + data = 2, // 2 должен инвертироваться в sync + sync = (uint8_t)~(uint8_t)2U // 253 должен инвертироваться в data + }; + + + volatile bool isSending = false; + // volatile bool genState = HIGH; + + volatile bool state; /// @brief Текущий уровень генерации + volatile uint8_t toggleCounter; /// @brief Счётчик переключений + volatile uint8_t preambBitCounter; + volatile uint8_t dataBitCounter; + volatile uint8_t syncBitCounter; + + volatile uint8_t preambFrontCounter; + volatile uint8_t dataFrontCounter; + volatile uint8_t syncFrontCounter; + + // uint8_t bitSequence[2]; + // volatile uint32_t toggle_counter; + + SignalPart signal; + + }; - //////////////////////////////////////////////////////////////////////////////////////////////// template diff --git a/IR_config.h b/IR_config.h index aa020f4..bc996a9 100644 --- a/IR_config.h +++ b/IR_config.h @@ -106,10 +106,10 @@ typedef uint16_t crc_t; #define carrierPeriod (1000000U/carrierFrec) // период несущей в us // В процессе работы значения будут отклонятся в соответствии с предыдущим битом -#define bitActiveTakts 25U // длительность единицы в тактах -#define bitPauseTakts 6U // длительность нуля в тактах +#define bitActiveTakts 25U // длительность высокого уровня в тактах +#define bitPauseTakts 6U // длительность низкого уровня в тактах -#define bitTakts (bitActiveTakts+bitPauseTakts*2U) // Общая длительность бита в тактах +#define bitTakts (bitActiveTakts+(bitPauseTakts*2U)) // Общая длительность бита в тактах #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита #define tolerance 300U