diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 07c0fc7..0a31fa4 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -17,214 +17,41 @@ IR_Decoder::~IR_Decoder() { delete dataBuffer; } -void IR_Decoder::writeToBuffer(bool bit) { - if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения - //TODO: Буффер переполнен! - isBufferOverflow = true; - } - if (isBufferOverflow || isPreamb || isWrongPack) return; - - // Переключение флага, data или syncBit - if (bufBitPos == nextControlBit) { - nextControlBit += (isData ? syncBits : bitPerByte); // маркер следующего переключения - isData = !isData; - i_syncBit = 0; // сброс счетчика битов синхронизации - err_syncBit = 0; // сброс счетчика ошибок синхронизации - Serial.print(" "); - } - - - if (isData) { // Запись битов в dataBuffer - Serial.print(bit); - - if (i_dataBuffer % 8 == 7) { - // Serial.print("+"); - } - dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer % 8); - i_dataBuffer++; - bufBitPos++; - } else { - //********************************* Проверка контрольных sync битов*******************************// - ////////////////////// Исправление лишнего нуля /////////////////////// - if (i_syncBit == 0) { // Первый бит синхронизации - // Serial.print("~"); - if (bit != (dataBuffer[((i_dataBuffer - 1) / 8)] >> (7 - (i_dataBuffer - 1) % 8) & 1)) { - bufBitPos++; - i_syncBit++; - } else { - i_syncBit = 0; - errorCounter++; - // Serial.print("E"); - err_syncBit++; - // Serial.print("bit: "); Serial.println(bit); - // Serial.print("dataBuffer: "); Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); - } - } else { // Последующие биты синхронизации - // Serial.print("`"); - bufBitPos++; - i_syncBit++; - } - ////////////////////// Проверка наличия битов синхранизации ////////////////////// - isWrongPack = err_syncBit >= syncBits; - if (isWrongPack) Serial.print("****************"); - }//**************************************************************************************************// - - // Serial.print(bit); -#ifdef IRDEBUG - bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); -#endif - - - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; - if ((i_dataBuffer >= (8 * msgBytes)) && !isMsgAvaliable) { - switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { - case IR_MSG_ACCEPT: - if (i_dataBuffer >= ((msgBytes + addrBytes + crcBytes) * bitPerByte)) { - 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 (i_dataBuffer >= ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte)) { - 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 (i_dataBuffer >= ((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte) { - // Serial.println("OK"); - const uint8_t dataSize = (dataBuffer[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) { -// if (!isRawAvaliable) { return nullptr; } -// if (dataBuffer != nullptr) { delete dataBuffer; dataBuffer = nullptr; } // устранение утечки памяти -// dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; // Буффер по максимуму - -// bool isData = true; -// bool controlCheckFirst = true; -// bool controlCheck; - -// uint8_t nextControlBit = bitPerByte; -// uint16_t i_dataBuffer = 0; -// for (uint16_t i = 0; i < dataBitSize; i++) { -// if (i == nextControlBit) { -// controlCheckFirst = true; -// nextControlBit += (isData ? syncBits : bitPerByte); -// isData = !isData; -// } - -// if (isData) { -// dataBuffer[i_dataBuffer / 8] |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1) << 7 - (i_dataBuffer % 8); -// i_dataBuffer++; -// } else { // Проверка контрольных sync битов -// if (controlCheckFirst) { -// controlCheck = (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); -// controlCheckFirst = false; -// } else { -// controlCheck |= (rawBuffer[(i / 8)] >> (7 - (i % 8)) & 1); -// } - -// } -// } - -// isFilterBufferAvaliable = controlCheck; -// if (reset) { resetAvaliable(); } -// return dataBuffer; -// } - -bool IR_Decoder::crcCheck(uint8_t len) { - bool crcOK = false; - - crcValue = 0; - crcValue = (crc8(dataBuffer, 0, len, poly1) << 8) & ~((crc_t)0xFF); - crcValue |= crc8(dataBuffer, 0, len + 1, poly2) & (crc_t)0xFF; - - if ( - crcValue && - dataBuffer[len] == (crcValue >> 8) & 0xFF && - dataBuffer[len + 1] == (crcValue & 0xFF) - ) { - crcOK = true; - } else { crcOK = false; } - - - return crcOK; -} - -void IR_Decoder::start_RX() { - // Serial.println(); - // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); - // Serial.println(); - - - resetAvaliable(); - isBufferOverflow = false; - memset(dataBuffer, 0x00, bufferDataSize); - - bufBitPos = 0; - isData = true; - i_dataBuffer = 0; - nextControlBit = bitPerByte; - i_syncBit = 0; - isWrongPack = false; -} - -void IR_Decoder::resetAvaliable() { - isRawAvaliable = false; - isMsgAvaliable = false; -} - -uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { - int ret = val / divider; - if ((val << 4) / divider - (ret << 4) >= 8) - ret++; - return ret; -} - -void IR_Decoder::listen() { - if (isRecive && micros() - prevRise > IR_timeout * 2) { - isRecive = false; - } -} - -//////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// isr /////////////////////////////////////////// + +void IR_Decoder::isr() { + if (isPairSending) return; + + subBuffer[currentSubBufferIndex].next = nullptr; + subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1; + subBuffer[currentSubBufferIndex].time = micros(); + + if (firstUnHandledFront == nullptr) { + firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их + } else { + if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его + firstUnHandledFront = firstUnHandledFront->next; + Serial.println(); + Serial.println("ERROR"); + Serial.println(); + } + } + + if (lastFront == nullptr) { + lastFront = &subBuffer[currentSubBufferIndex]; + } else { + lastFront->next = &subBuffer[currentSubBufferIndex]; + lastFront = &subBuffer[currentSubBufferIndex]; + } + + + currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; // Закольцовка буффера +} + //////////////////////////////////////////////////////////////////////////////////// void IR_Decoder::tick() { + listen(); if (firstUnHandledFront == nullptr) return; //Если данных нет - ничего не делаем FrontStorage currentFront; @@ -240,11 +67,11 @@ void IR_Decoder::tick() { errorCounter = 0; isRecive = true; isPreamb = true; - // frontCounter = preambFronts - 1U; + // preambFrontCounter = preambFronts - 1U; // } else { // ↑ riseSyncTime = bitTime /* 1100 */; start_RX(); - frontCounter = preambFronts - 1U; + preambFrontCounter = preambFronts - 1U; // } @@ -252,24 +79,24 @@ void IR_Decoder::tick() { // Serial.print("currentFront.time: "); Serial.println(currentFront.time); // Serial.print("currentFront.dir: "); Serial.println(currentFront.dir ? "UP" : "Down"); // Serial.print("prevRise: "); Serial.println(prevRise); - // Serial.print("frontCounter: "); Serial.println(frontCounter); + // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); // prevRise = currentFront.time; } - if (frontCounter > 0) { // в преамбуле + if (preambFrontCounter > 0) { // в преамбуле uint32_t risePeriod = currentFront.time - prevRise; if (currentFront.dir && risePeriod < IR_timeout) { // __/``` ↑ и мы в внутри пакета if (risePeriod < riseTimeMin << 1) { // fix рваной единицы - frontCounter += 2; + preambFrontCounter += 2; errorCounter++; } else { if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner } } else { /* riseSyncTime = bitTime; */ } // сброс тюнера - frontCounter--; - // Serial.print("frontCounter: "); Serial.println(frontCounter); + preambFrontCounter--; + // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); } else { if (isPreamb) {// первый фронт после gotTune._set(riseSyncTime); @@ -403,7 +230,7 @@ void IR_Decoder::tick() { } } - if (isPreamb && frontCounter <= 0) { + if (isPreamb && preambFrontCounter <= 0) { prevRise = currentFront.time + riseTime; } @@ -414,187 +241,170 @@ void IR_Decoder::tick() { firstUnHandledFront = firstUnHandledFront->next; //переместить флаг на следующий элемент для обработки (next or nullptr) } -void IR_Decoder::isr() { // в прерывании вызываем isr() - if (isPairSending) return; - - subBuffer[currentSubBufferIndex].next = nullptr; - subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1; - subBuffer[currentSubBufferIndex].time = micros(); - - if (firstUnHandledFront == nullptr) { - firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их - } else { - if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его - firstUnHandledFront = firstUnHandledFront->next; - Serial.println(); - Serial.println("ERROR"); - Serial.println(); - } +void IR_Decoder::listen() { + if (isRecive && micros() - prevRise > IR_timeout * 2) { + isRecive = false; } - - if (lastFront == nullptr) { - lastFront = &subBuffer[currentSubBufferIndex]; - } else { - lastFront->next = &subBuffer[currentSubBufferIndex]; - lastFront = &subBuffer[currentSubBufferIndex]; - } - - - currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++; // Закольцовка буффера } +void IR_Decoder::start_RX() { + // Serial.println(); + // Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN)); + // Serial.println(); -void IR_Decoder::noFunc() { - //////////////////////////////////////////////////////////////////////////////////////////////////////////// - if (micros() - prevRise > IR_timeout && (PIND >> isrPin) & 1) { // первый - isRecive = true; - isPreamb = true; - frontCounter = preambFronts - 1U; - errorCounter = 0; - riseSyncTime = bitTime /* 1100 */; - start_RX(); - Serial.println("First!"); + resetAvaliable(); + isBufferOverflow = false; + memset(dataBuffer, 0x00, bufferDataSize); + + bufBitPos = 0; + isData = true; + i_dataBuffer = 0; + nextControlBit = bitPerByte; + i_syncBit = 0; + isWrongPack = false; +} + +void IR_Decoder::writeToBuffer(bool bit) { + if (i_dataBuffer >= bufferDataSize * 8 - 1) {// проверка переполнения + //TODO: Буффер переполнен! + isBufferOverflow = true; } - if (frontCounter > 0) { // в преамбуле - uint32_t risePeriod = micros() - prevRise; - if ((PIND >> isrPin) & 1 && risePeriod < IR_timeout) { // __/``` ↑ и мы в внутри пакета + if (isBufferOverflow || isPreamb || isWrongPack) return; - if (risePeriod < riseTimeMin << 1) { // fix рваной единицы - frontCounter += 2; - errorCounter++; + // Переключение флага, data или syncBit + if (bufBitPos == nextControlBit) { + nextControlBit += (isData ? syncBits : bitPerByte); // маркер следующего переключения + isData = !isData; + i_syncBit = 0; // сброс счетчика битов синхронизации + err_syncBit = 0; // сброс счетчика ошибок синхронизации + Serial.print(" "); + } + + + if (isData) { // Запись битов в dataBuffer + Serial.print(bit); + + if (i_dataBuffer % 8 == 7) { + // Serial.print("+"); + } + dataBuffer[(i_dataBuffer / 8)] |= bit << (7 - i_dataBuffer % 8); // Запись в буффер + i_dataBuffer++; + bufBitPos++; + } else { + //********************************* Проверка контрольных sync битов*******************************// + ////////////////////// Исправление лишнего нуля /////////////////////// + if (i_syncBit == 0) { // Первый бит синхронизации + // Serial.print("~"); + if (bit != (dataBuffer[((i_dataBuffer - 1) / 8)] >> (7 - (i_dataBuffer - 1) % 8) & 1)) { + bufBitPos++; + i_syncBit++; } else { - if (freeFrec) { riseSyncTime = (riseSyncTime + risePeriod / 2) / 2; } // tuner + i_syncBit = 0; + errorCounter++; + // Serial.print("E"); + err_syncBit++; + // Serial.print("bit: "); Serial.println(bit); + // Serial.print("dataBuffer: "); Serial.println(dataBuffer[((i_dataBuffer - 1) / 8)] & 1 << (7 - ((i_dataBuffer - 1) & ~(~0 << 3)))); } - } else { /* riseSyncTime = bitTime; */ } // сброс тюнера - frontCounter--; - //Serial.println(frontCounter); - } else { - if (isPreamb) {// первый фронт после - gotTune._set(riseSyncTime); + } else { // Последующие биты синхронизации + // Serial.print("`"); + bufBitPos++; + i_syncBit++; } - isPreamb = false; - } - - // определить направление фронта - if ((PIND >> isrPin) & 1) { // Если __/``` ↑ - - uint16_t risePeriod = micros() - prevRise; - uint16_t highTime = micros() - prevFall; - uint16_t lowTime = prevFall - prevRise; - - int8_t highCount = 0; - int8_t lowCount = 0; - int8_t allCount = 0; - - if (risePeriod < IR_timeout && !isBufferOverflow && risePeriod > riseTimeMin) { - // Мы в пределах таймаута и буффер не переполнен и fix дроблёных единиц - - - if (aroundRise(risePeriod)) { // тактирование есть, сигнал хороший - без ошибок(?) - - if (highTime > riseTimeMin >> 1) { // 1 - #ifdef IRDEBUG - digitalWrite(wrHigh, 1); - #endif - writeToBuffer(HIGH); - } else { // 0 - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - writeToBuffer(LOW); - } - - } else { // пропущены такты! сигнал средний // ошибка пропуска - - - highCount = ceil_div(highTime, riseTime); // предполагаемое колличество HIGH битов - lowCount = ceil_div(lowTime, riseTime); // предполагаемое колличество LOW битов - allCount = ceil_div(risePeriod, riseTime); // предполагаемое колличество всего битов - - if (highCount == 0 && highTime > riseTime / 3) { // fix короткой единицы (?)после пропуска нулей(?) - highCount++; - errorCounter++; - #ifdef IRDEBUG - errPulse(errOut, 2); - #endif - } - - if (lowCount + highCount > allCount) { // fix ошибочных сдвигов - if (lowCount > highCount) { // Лишние нули - lowCount = allCount - highCount; - #ifdef IRDEBUG - errPulse(errOut, 3); - #endif - } else if (lowCount < highCount) { // Лишние единицы - highCount = allCount - lowCount; - #ifdef IRDEBUG - errPulse(errOut, 4); - #endif - } else if (lowCount == highCount) {} // неизвестный случай - errorCounter += allCount; - } - - errorCounter += allCount; - #ifdef IRDEBUG - errPulse(errOut, 1); - #endif - - - for (int8_t i = 0; i < lowCount && 8 - i; i++) { // отправка LOW битов, если есть - #ifdef IRDEBUG - digitalWrite(wrLow, 1); - #endif - writeToBuffer(LOW); - } - - for (int8_t i = 0; i < highCount && 8 - i; i++) { // отправка HIGH битов, если есть - #ifdef IRDEBUG - digitalWrite(wrHigh, 1); - #endif - writeToBuffer(HIGH); - } - - } - - #ifdef IRDEBUG - digitalWrite(wrHigh, 0); - digitalWrite(wrLow, 0); - #endif - } - - if (risePeriod > riseTimeMax >> 1 || highCount || lowCount) { // комплексный фикс рваной единицы - prevPrevRise = prevRise; - prevRise = micros(); - } else { - errorCounter++; - #ifdef IRDEBUG - errPulse(errOut, 5); - #endif - } - - } else { // Если ```\__ ↓ - - if (micros() - prevFall > riseTimeMin) { - prevPrevFall = prevFall; - prevFall = micros(); - } else { - #ifdef IRDEBUG - //errPulse(errOut, 5); - #endif - } - } - - if (isPreamb && frontCounter <= 0) { - prevRise = micros() + riseTime; - } + ////////////////////// Проверка наличия битов синхранизации ////////////////////// + isWrongPack = err_syncBit >= syncBits; + if (isWrongPack) Serial.print("****************"); + }//**************************************************************************************************// + // Serial.print(bit); #ifdef IRDEBUG - digitalWrite(writeOp, isPreamb); + bit ? infoPulse(writeOp, 2) : infoPulse(writeOp, 1); #endif - //////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + //const auto testval = bufferBitSizeMax; + if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { + uint16_t crcValue; + switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + case IR_MSG_ACCEPT: + if (i_dataBuffer >= ((msgBytes + addrBytes + crcBytes) * bitPerByte)) { + const uint8_t dataSize = msgBytes + addrBytes; + isCrcCorrect = crcCheck(dataSize, crcValue); + if (isCrcCorrect && checkAddr(1, 2)) { + gotAccept._set(dataBuffer, msgBytes + addrBytes + crcBytes, crcValue, errorCounter, riseSyncTime); + gotAccept._isAvaliable = true; + } + } + break; + + case IR_MSG_REQUEST: + if (i_dataBuffer >= ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte)) { + const uint8_t dataSize = msgBytes + addrBytes + addrBytes; + isCrcCorrect = (crcCheck(dataSize, crcValue)); + if (isCrcCorrect && 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 (i_dataBuffer >= ((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte) { + // Serial.println("OK"); + const uint8_t dataSize = (dataBuffer[0] & IR_MASK_MSG_INFO); + isCrcCorrect = crcCheck(dataSize, crcValue); + if (isCrcCorrect && 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; + } + }/**/ + ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } +bool IR_Decoder::crcCheck(uint8_t len, uint16_t &crc) { + bool crcOK = false; + + crc = 0; + crc = (crc8(dataBuffer, 0, len, poly1) << 8) & ~((crc_t)0xFF); + crc |= crc8(dataBuffer, 0, len + 1, poly2) & (crc_t)0xFF; + + if ( + crc && + dataBuffer[len] == (crc >> 8) & 0xFF && + dataBuffer[len + 1] == (crc & 0xFF) + ) { + crcOK = true; + } else { crcOK = false; } + + + return crcOK; +} + +void IR_Decoder::resetAvaliable() { + isCrcCorrect = false; +} + +uint16_t IR_Decoder::ceil_div(uint16_t val, uint16_t divider) { + int ret = val / divider; + if ((val << 4) / divider - (ret << 4) >= 8) + ret++; + return ret; +} + + // IRDEBUG FUNC #ifdef IRDEBUG diff --git a/IR_Decoder.h b/IR_Decoder.h index becdaba..da05118 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -21,25 +21,31 @@ #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define IR_timeout (riseTimeMax * (8 + syncBits +1)) // us // таймаут в 8 data + 3 sync + 1 -#define subBufferSize 5 //Буфер для складирования фронтов, пока их не обработают +#define subBufferSize 7 //Буфер для складирования фронтов, пока их не обработают class IR_Encoder; class IR_Decoder : private IR_FOX { friend IR_Encoder; public: uint16_t addrSelf; - + /// @brief Конструктор + /// @param isrPin Номер вывода прерывания/данных от приёмника (2 или 3 для atmega 328p) + /// @param addr Адрес приёмника + /// @param encPair Указатель на передатчик, работающий в паре IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr); ~IR_Decoder(); - // @brief Для прерывания + // @brief Функция прерывания void isr(); + /// @brief Обработка приёмника, необходима для работы void tick(); // @return Буффер переполнился bool isOverflow() { return isBufferOverflow; }; + /// @brief Флаг приёма + /// @return Возвращает true, если происходит приём пакета bool isReciving() { return isRecive; }; // @brief Слушатель для работы isReciving() void listen(); @@ -157,58 +163,51 @@ public: } }; + /// @brief Контейнер с данными Data gotData; Data gotRawData; - // RawData gotRawData; + /// @brief Контейнер с подтверждением Accept gotAccept; + /// @brief Контейнер с запросом Request gotRequest; + /// @brief Контейнер с информацией подстройки RawTune gotTune; private: - const uint8_t isrPin; + const uint8_t isrPin; // Пин прерывания - IR_Encoder* encoder; - bool isPairSending = false; - bool IsPairSendLOW = false; + IR_Encoder* encoder; // Указатель на парный передатчик + bool isPairSending = false; // Флаг передачи парного передатчика + bool IsPairSendLOW = false; // - volatile bool isRecive = false; + volatile bool isRecive = false; // Флаг приёма - bool isWaitingAccept = false; - uint16_t addrWaitingFrom = 0; + bool isWaitingAccept = false; // Флаг ожидания подтверждения + uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение - uint16_t addrFrom = 0; + uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс - uint16_t riseSyncTime = bitTime; + bool isCrcCorrect = false; // Флаг корректности crc + bool isBufferOverflow = false; // Флаг переполнения буффера данных + bool isWrongPack = false; // Флаг битого пакета - volatile bool isRawAvaliable = false; + volatile bool isPreamb = false; // флаг начальной последовости + bool HIGH_FIRST = true; //TODO: порядок приходящих битов - volatile bool isMsgAvaliable = false; - - volatile bool isBufferOverflow = false; - bool isWrongPack = false; - - volatile bool isPreamb = false; // флаг начальной последовости - bool HIGH_FIRST = true; // порядок приходящих битов - - //Буффер - // const uint8_t bufferRawSize = - // ((bufferBitSizeMax % 8 > 0) ? - // (bufferBitSizeMax / 8) + 1 : - // (bufferBitSizeMax / 8)); const uint8_t bufferDataSize = dataByteSizeMax; // + crc //////////////////////////////////////////////////////////////////////// void noFunc(); - volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов - // Структура для хранения времени и направления фронта/спада - struct FrontStorage { - volatile uint32_t time; // Время - volatile bool dir; // Направление (true = ↑; false = ↓) - volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец + volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов + + struct FrontStorage { // Структура для хранения времени и направления фронта/спада + 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; @@ -220,23 +219,27 @@ private: volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов //////////////////////////////////////////////////////////////////////// - // uint8_t* rawBuffer = nullptr; - uint8_t* dataBuffer = nullptr; + uint8_t* dataBuffer = nullptr; // Указатель на буффер данных + uint32_t prevRise,prevPrevRise, prevFall, prevPrevFall; // Время предыдущих фронтов/спадов + uint16_t errorCounter = 0; // Счётчик ошибок + int8_t preambFrontCounter = 0; // Счётчик __/``` ↑ преамбулы + int16_t bufBitPos = 0; // Позиция для записи бита в буффер - volatile uint32_t prevRise, prevFall, prevPrevFall, prevPrevRise; - volatile uint16_t errorCounter = 0; - volatile int8_t frontCounter = 0; - volatile int16_t bufBitPos = 0; - crc_t crcValue = 0; private: - uint8_t* getDataBuffer(bool reset = false); - bool crcCheck(uint8_t len); + /// @brief Проверка CRC. Проверяет len байт со значением crc, пришедшим в пакете + /// @param len Длина в байтах проверяемых данных + /// @param crc Результат рассчёта crc (Выходной параметр) + /// @return true если crc верно + bool crcCheck(uint8_t len, uint16_t &crc); //////////////////////////////////////////////////////////////////////// bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации uint16_t i_dataBuffer; // Счётчик буфера данных uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData uint8_t i_syncBit; // Счётчик битов синхронизации uint8_t err_syncBit; // Счётчик ошибок синхронизации + + /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация + /// @param Бит данных void writeToBuffer(bool); //////////////////////////////////////////////////////////////////////// diff --git a/IR_config.h b/IR_config.h index b7f898b..4614402 100644 --- a/IR_config.h +++ b/IR_config.h @@ -132,7 +132,7 @@ protected: } return crc; } -public: +// public: /// @brief Вывод массива байт в строковом формате /// @param d Указатель на массив /// @param s Размер массива