From d629b24864cfd9a4bf490c50691f80f0698f8550 Mon Sep 17 00:00:00 2001 From: DashyFox Date: Wed, 24 Jan 2024 16:13:03 +0300 Subject: [PATCH] fix extra zero, docs and debag --- IR_Decoder.cpp | 203 +++++++++++++++++++++++++++++++------------------ IR_Decoder.h | 31 +++++--- IR_config.h | 2 +- 3 files changed, 149 insertions(+), 87 deletions(-) diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 9293ef9..a3f19af 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -8,6 +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 = rawBuffer; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; start_RX(); } @@ -17,73 +18,117 @@ IR_Decoder::~IR_Decoder() { } void IR_Decoder::writeToBuffer(bool bit) { - if (!isBufferOverflow && !isPreamb) { - if (HIGH_FIRST) { - rawBuffer[(bufBitPos >> 3)] |= bit << (7 - (bufBitPos & ~(~0 << 3))); - }/* else { - rawBuffer[(bufBitPos >> 3)] |= bit << (bufBitPos & ~(~0 << 3)); - } */ - Serial.print(bit); - #ifdef IRDEBUG - bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); - #endif + if (isBufferOverflow || isPreamb) return; - if (isBufferOverflow) { //TODO: Буффер переполнен! - - } -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; - if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { - switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { - case IR_MSG_ACCEPT: - if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(1, 2)) { - gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - gotAccept._isAvaliable = true; - } - } - break; - - case IR_MSG_REQUEST: - if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { - const uint8_t dataSize = msgBytes + addrBytes + addrBytes; - isRawAvaliable = true; - isMsgAvaliable = (crcCheck(dataSize)); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotRequest._isAvaliable = true; - gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); - } - } - break; - - - case IR_MSG_DATA_ACCEPT: - case IR_MSG_DATA_NOACCEPT: - if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) { - const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO); - isRawAvaliable = true; - isMsgAvaliable = crcCheck(dataSize); - if (isMsgAvaliable && checkAddr(3, 4)) { - gotData._isAvaliable = true; - gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } else { - gotRawData._isAvaliable = true; - gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); - } - } - break; - - default: - break; - } - } -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; } - bufBitPos++; + // Переключение флага, data или syncBit + if (bufBitPos == nextControlBit) { + nextControlBit += (isData ? syncBits : bitPerByte); + isData = !isData; + Serial.print(" "); } + Serial.print(bit); + + if (isData) { // Запись битов в dataBuffer + dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer%8); + i_dataBuffer++; + bufBitPos++; + i_syncBit = 0; + } else { // Проверка контрольных sync битов + if (i_syncBit == 0) { // Первый бит синхронизации + if (bit != dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))) { + bufBitPos++; + } else { + errorCounter++; + Serial.print("E"); + // Serial.print("bit: ");Serial.println(bit); + // Serial.print("dataBuffer: ");Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); + } + } else { // Последующие биты синхронизации + bufBitPos++; + } + + i_syncBit++; + } + + // if (bufBitPos >= bufferRawSize * 8 - 1) { isBufferOverflow = true; } + + + + + + + + + + + + + + + + + + + + /* +#ifdef IRDEBUG + bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); +#endif + + if (isBufferOverflow) { //TODO: Буффер переполнен! + + } + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //const auto testval = bufferBitSizeMax; + if ((bufBitPos >= (8 * msgBytes) - syncBits) && !isMsgAvaliable) { + switch ((rawBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + case IR_MSG_ACCEPT: + if (bufBitPos >= ((msgBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { + const uint8_t dataSize = msgBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(1, 2)) { + gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotAccept._isAvaliable = true; + } + } + break; + + case IR_MSG_REQUEST: + if (bufBitPos >= ((msgBytes + addrBytes + addrBytes + crcBytes) * (8 + 3)) - syncBits) { + const uint8_t dataSize = msgBytes + addrBytes + addrBytes; + isRawAvaliable = true; + isMsgAvaliable = (crcCheck(dataSize)); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotRequest._isAvaliable = true; + gotRequest._set(dataBuffer, msgBytes + addrBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + } + } + break; + + + case IR_MSG_DATA_ACCEPT: + case IR_MSG_DATA_NOACCEPT: + if (bufBitPos >= ((bitPerByte + syncBits) * ((rawBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)) - syncBits) { + const uint8_t dataSize = (rawBuffer[0] & IR_MASK_MSG_INFO); + isRawAvaliable = true; + isMsgAvaliable = crcCheck(dataSize); + if (isMsgAvaliable && checkAddr(3, 4)) { + gotData._isAvaliable = true; + gotData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } else { + gotRawData._isAvaliable = true; + gotRawData._set(dataBuffer, (dataSize)+crcBytes, crcValue, errorCounter, riseSyncTime); + } + } + break; + + default: + break; + } + }/**/ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + } uint8_t* IR_Decoder::getDataBuffer(bool reset = false) { @@ -149,10 +194,20 @@ bool IR_Decoder::crcCheck(uint8_t len) { } void IR_Decoder::start_RX() { + // Serial.println(); + // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); + // Serial.println(); + + resetAvaliable(); isBufferOverflow = false; memset(rawBuffer, 0x00, bufferRawSize); + bufBitPos = 0; + isData = true; + i_dataBuffer = 0; + nextControlBit = bitPerByte; + i_syncBit = 0; } void IR_Decoder::resetAvaliable() { @@ -308,14 +363,14 @@ void IR_Decoder::tick() { void IR_Decoder::isr() { // в прерывании вызываем isr() if (isPairSending) return; - frontBuffer[currentFrontBufferWriteIndex].next = nullptr; - frontBuffer[currentFrontBufferWriteIndex].dir = (PIND >> isrPin) & 1; - frontBuffer[currentFrontBufferWriteIndex].time = micros(); + subBuffer[currentSubBufferIndex].next = nullptr; + subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1; + subBuffer[currentSubBufferIndex].time = micros(); if (firstUnHandledFront == nullptr) { - firstUnHandledFront = &frontBuffer[currentFrontBufferWriteIndex]; // Если нет необработанных данных - добавляем их + firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их } else { - if (firstUnHandledFront == &frontBuffer[currentFrontBufferWriteIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его + if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его firstUnHandledFront = firstUnHandledFront->next; Serial.println(); Serial.println("ERROR"); @@ -324,14 +379,14 @@ void IR_Decoder::isr() { // в прерывании вызываем isr() } if (lastFront == nullptr) { - lastFront = &frontBuffer[currentFrontBufferWriteIndex]; + lastFront = &subBuffer[currentSubBufferIndex]; } else { - lastFront->next = &frontBuffer[currentFrontBufferWriteIndex]; - lastFront = &frontBuffer[currentFrontBufferWriteIndex]; + lastFront->next = &subBuffer[currentSubBufferIndex]; + lastFront = &subBuffer[currentSubBufferIndex]; } - currentFrontBufferWriteIndex == (subBuffer - 1) ? currentFrontBufferWriteIndex = 0 : currentFrontBufferWriteIndex++; + currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; } diff --git a/IR_Decoder.h b/IR_Decoder.h index 6eec030..eac7a12 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -21,7 +21,7 @@ #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1 -#define subBuffer 5 //Буфер для складирования фронтов, пока их не обработают +#define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают class IR_Encoder; class IR_Decoder : private IR_FOX { @@ -200,13 +200,15 @@ private: const uint8_t bufferDataSize = dataByteSizeMax; // + crc //////////////////////////////////////////////////////////////////////// void noFunc(); - volatile uint8_t currentFrontBufferWriteIndex; + volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов + // Структура для хранения времени и направления фронта/спада struct FrontStorage { - volatile uint32_t time; - volatile bool dir; - volatile FrontStorage* next; + volatile uint32_t time; // Время + volatile bool dir; // Направление (true = ↑; false = ↓) + volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец - FrontStorage& operator= (FrontStorage& val) { + // Операторо присвоения + FrontStorage& operator= (FrontStorage& val) { this->next = val.next; this->time = val.time; this->dir = val.dir; @@ -214,9 +216,9 @@ private: return *this; } }; - volatile FrontStorage* lastFront = nullptr; - volatile FrontStorage* firstUnHandledFront = nullptr; - volatile FrontStorage frontBuffer[subBuffer]; + volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада + volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада + volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов //////////////////////////////////////////////////////////////////////// uint8_t* rawBuffer = nullptr; uint8_t* dataBuffer = nullptr; @@ -229,9 +231,14 @@ private: private: uint8_t* getDataBuffer(bool reset = false); bool crcCheck(uint8_t len); - - inline void writeToBuffer(bool); - inline void start_RX(); + //////////////////////////////////////////////////////////////////////// + bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации + uint16_t i_dataBuffer; // Счётчик буфера данных + uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData + uint8_t i_syncBit; // Счётчик битов синхронизации + void writeToBuffer(bool); + //////////////////////////////////////////////////////////////////////// + void start_RX(); void resetAvaliable(); uint16_t ceil_div(uint16_t, uint16_t); diff --git a/IR_config.h b/IR_config.h index abb8b5b..b7f898b 100644 --- a/IR_config.h +++ b/IR_config.h @@ -146,7 +146,7 @@ public: case 2: for (size_t i = 0; i < s * 8; i++) { if (i == control) { - str += " "; + str += " "; control += bitPerByte; }