diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index cb9cdfd..d652c9b 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -8,7 +8,7 @@ IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), addrSelf(addr), encoder(encPair) { // rawBuffer = new uint8_t[bufferRawSize] { 0 }; - dataBuffer = new uint8_t[bufferDataSize] { 0 }; + dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; start_RX(); } @@ -255,7 +255,7 @@ void IR_Decoder::start_RX() { resetAvaliable(); isBufferOverflow = false; - memset(dataBuffer, 0x00, bufferDataSize); + memset(dataBuffer, 0x00, dataByteSizeMax); bufBitPos = 0; isData = true; @@ -266,7 +266,7 @@ void IR_Decoder::start_RX() { } void IR_Decoder::writeToBuffer(bool bit) { - if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения + if (i_dataBuffer >= dataByteSizeMax * 8 - 1) {// проверка переполнения //TODO: Буффер переполнен! isBufferOverflow = true; } diff --git a/IR_Decoder.h b/IR_Decoder.h index 36e6cb8..40ed47d 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -197,7 +197,6 @@ private: volatile bool isPreamb = false; // флаг начальной последовости bool HIGH_FIRST = true; //TODO: порядок приходящих битов - const uint8_t bufferDataSize = dataByteSizeMax; // + crc //////////////////////////////////////////////////////////////////////// void noFunc(); volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index e187c44..7dc47f5 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -1,7 +1,12 @@ #include "IR_Encoder.h" #include "IR_Decoder.h" +#define LoopOut 12 +#define ISR_Out 10 +#define TestOut 13 + IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* decPair) { + sendBuffer = new uint8_t[dataByteSizeMax] { 0 }; ir_out = pin; pinMode(ir_out, OUTPUT); addrSelf = addr; @@ -16,6 +21,7 @@ IR_Encoder::IR_Encoder(uint16_t addr, uint8_t pin, uint8_t tune = 0, IR_Decoder* IR_Encoder::~IR_Encoder() { delete [] bitHigh; delete [] bitLow; + delete [] sendBuffer; }; void IR_Encoder::sendACK(uint16_t addrTo, uint8_t addInfo, bool forAll = false) { @@ -109,74 +115,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) { - cli(); digitalToggle(9); digitalToggle(9); + memset(sendBuffer, 0x00, dataByteSizeMax); + memcpy(sendBuffer, ptr, len); + sendLen = len; + // *sendBuffer = 0b10010011; isSending = true; + + cli(); if (decoder != nullptr) { decoder->isPairSending = isSending; } // #define preambToggle 2*2-1 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< toggleCounter = preambToggle; // Первая генерация для первого signal - preambBitCounter; - dataBitCounter = 3/* len * 8 */; - syncBitCounter = syncBits; + dataBitCounter = bitPerByte - 1; + dataByteCounter = 0; preambFrontCounter = preambPulse * 2 - 1; // -1 за счёт генерации уже на этапе сразу после инициализации - dataFrontCounter = bitPerByte * 2; - syncFrontCounter; + dataSequenceCounter = bitPerByte * 2; + syncSequenceCounter = syncBits * 2; signal = preamb; isSending = true; state = HIGH; - currentBit = bitHigh; + currentBitSequence = bitHigh; sei(); } + void IR_Encoder::isr() { if (!isSending) return; ir_out_virtual = !ir_out_virtual && state; - if (toggleCounter == 0) { - + if (toggleCounter) { + toggleCounter--; + } else { IsrStart: switch (signal) { case noSignal: + // сброс счетчиков + // ... isSending = false; return; break; case preamb: - if (preambFrontCounter == 0) { // Конец преамбулы, переход на следующий signal + if (preambFrontCounter) { + preambFrontCounter--; + toggleCounter = preambToggle; // Вторая и последующие генерации для этого signal + } else {// Конец преамбулы, переход на следующий signal signal = data; state = !LOW; // Инверсное состояние первой генерации следующего signal goto IsrStart; // Применение новых параметров в этй же итерации прерывания - } else { - preambFrontCounter--; - toggleCounter = preambToggle; // Вторая и последующие генерации для этого signal } break; case data: - if (dataFrontCounter == 0) { // Конец преамбулы, переход на следующий signal - signal = noSignal; - // state = HIGH; - isSending = false; - } else { - toggleCounter = currentBit[!state]; - dataFrontCounter--; + if (dataSequenceCounter) { + if (!(dataSequenceCounter & 1U)) { // если чётный - смена бита + currentBitSequence = ((sendBuffer[dataByteCounter] >> dataBitCounter) & 1U) ? bitHigh : bitLow; // определение текущего бита + dataBitCounter--; + } + toggleCounter = currentBitSequence[!state]; + dataSequenceCounter--; + } else { // Конец data, переход на следующий signal + syncLastBit = !((sendBuffer[dataByteCounter]) & 1U); + dataByteCounter++; + dataBitCounter = bitPerByte - 1; + dataSequenceCounter = bitPerByte * 2; + signal = sync; + goto IsrStart; // Применение новых параметров в этй же итерации прерывания } - - - // signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 break; case sync: - // signal = (SignalPart)(~signal); // 2 -> 253, 253 -> 2 + if (syncSequenceCounter) { + if (!(syncSequenceCounter & 1U)) { // если чётный - смена бита + if (syncSequenceCounter == 2) { // Если последний бит + currentBitSequence = ((sendBuffer[dataByteCounter]) & 0b10000000) ? bitLow : bitHigh; + } else { + currentBitSequence = syncLastBit ? bitLow : bitHigh; // определение текущего бита + syncLastBit = !syncLastBit; + } + } + toggleCounter = currentBitSequence[!state]; + syncSequenceCounter--; + } else { // Конец sync, переход на следующий signal + signal = data; + syncSequenceCounter = syncBits * 2; + + if (dataByteCounter >= sendLen) { // определение конца данных + signal = noSignal; + } + goto IsrStart; // Применение новых параметров в этй же итерации прерывания + } break; default: @@ -185,9 +222,7 @@ void IR_Encoder::isr() { } state = !state; - - - } else { toggleCounter--; } + } } diff --git a/IR_Encoder.h b/IR_Encoder.h index ae30c07..cdbdb9c 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -46,23 +46,27 @@ private: enum SignalPart : uint8_t { noSignal = 0, preamb = 1, - data = 2, // 2 должен инвертироваться в sync - sync = (uint8_t)~(uint8_t)2U // 253 должен инвертироваться в data + data = 2, + sync = 3 }; + uint8_t sendLen; + uint8_t* sendBuffer; /// @brief Буффер данных для отправки volatile bool isSending = false; // volatile bool genState = HIGH; - volatile bool state; /// @brief Текущий уровень генерации - volatile uint8_t toggleCounter; /// @brief Счётчик переключений - volatile uint8_t preambBitCounter; + volatile bool state; /// @brief Текущий уровень генерации + + volatile uint8_t dataByteCounter; + + volatile uint8_t toggleCounter; /// @brief Счётчик переключений volatile uint8_t dataBitCounter; - volatile uint8_t syncBitCounter; volatile uint8_t preambFrontCounter; - volatile uint8_t dataFrontCounter; - volatile uint8_t syncFrontCounter; + volatile uint8_t dataSequenceCounter; + volatile uint8_t syncSequenceCounter; + volatile bool syncLastBit; struct BitSequence { uint8_t low; @@ -76,7 +80,7 @@ private: (bitPauseTakts + bitActiveTakts) * 2 - 1, (bitPauseTakts) * 2 - 1 }; - uint8_t* currentBit; + uint8_t* currentBitSequence = bitLow; // uint8_t bitSequence[2]; diff --git a/IR_config.h b/IR_config.h index bc996a9..c4eaacb 100644 --- a/IR_config.h +++ b/IR_config.h @@ -96,8 +96,8 @@ typedef uint16_t crc_t; #define dataByteSizeMax (msgBytes + addrBytes + addrBytes + bytePerPack + crcBytes) // размер msg в битах // размер короткой посылки в битах -#define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах -#define bufferBitSizeMax (dataBitSize) // Размер буффера в битах +// #define dataBitSize ((8 + syncBits) * dataByteSizeMax) // размер посылки с данными в битах +// #define bufferBitSizeMax (dataBitSize) // Размер буффера в битах //const auto x = bufferBitSizeMax; #define preambFronts (preambPulse*2) // количество фронтов преамбулы @@ -113,6 +113,8 @@ typedef uint16_t crc_t; #define bitTime (bitTakts*carrierPeriod) // Общая длительность бита #define tolerance 300U + #define preambToggle ((bitPauseTakts * 2 + bitActiveTakts) * 2 - 1) + class IR_FOX { private: