diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index 29a3830..6803bcc 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -9,10 +9,8 @@ ) IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), id(addr), encoder(encPair) { - // rawBuffer = new uint8_t[bufferRawSize] { 0 }; dataBuffer = new uint8_t[dataByteSizeMax] { 0 }; prevRise = prevFall = prevPrevFall = prevPrevRise = 0; - // start_RX(); } IR_Decoder::~IR_Decoder() { @@ -35,7 +33,7 @@ void IR_Decoder::isr() { firstUnHandledFront = firstUnHandledFront->next; #ifdef IRDEBUG_INFO // Serial.println(); - // Serial.println("ERROR"); + Serial.println(" ISR BUFFER OVERFLOW "); // Serial.println(); #endif } @@ -124,7 +122,7 @@ void IR_Decoder::tick() { // Serial.print("preambFrontCounter: "); Serial.println(preambFrontCounter); } else { if (isPreamb) {// первый фронт после - gotTune.set(dataBuffer, 1, 0, errors, riseSyncTime); + gotTune.set(riseSyncTime); } isPreamb = false; } @@ -350,7 +348,7 @@ void IR_Decoder::writeToBuffer(bool bit) { /////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - //const auto testval = bufferBitSizeMax; + #ifdef IRDEBUG_INFO if (isData) { if (i_dataBuffer == ((msgBytes)*bitPerByte)) { Serial.print(" -> "); Serial.print(dataBuffer[0] & IR_MASK_MSG_INFO); Serial.print(" ->"); } @@ -363,21 +361,46 @@ void IR_Decoder::writeToBuffer(bool bit) { if ((i_dataBuffer >= (8 * msgBytes)) && !isCrcCorrect) { uint16_t crcValue; switch ((dataBuffer[0] >> 5) & IR_MASK_MSG_TYPE) { + + case IR_MSG_BACK: + packToOutClass( + (((dataBuffer[0] & (IR_MASK_MSG_INFO >> 1)) + crcBytes)), // packSize + gotData, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + NULL, // addrToOffset + 3, // dataOffset + NULL // crcOffset + } + ); + break; + case IR_MSG_ACCEPT: packToOutClass( - ((msgBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset - (msgBytes + addrBytes), // bytesToCheck - 1, // addressForCheck_Offset - &gotAccept // objFine + ((msgBytes + addrBytes + crcBytes)), // packSize + gotAccept, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + NULL, // addrToOffset + NULL, // dataOffset + 3 // crcOffset + } ); break; case IR_MSG_REQUEST: packToOutClass( - ((msgBytes + addrBytes + addrBytes + crcBytes) * bitPerByte), // endBitOffset - (msgBytes + addrBytes + addrBytes), // bytesToCheck - 3, // addressForCheck_Offset - &gotRequest // objFine + ((msgBytes + addrBytes + addrBytes + crcBytes)), // packSize + gotRequest, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + 3, // addrToOffset + NULL, // dataOffset + 5 // crcOffset + } ); break; @@ -385,11 +408,15 @@ void IR_Decoder::writeToBuffer(bool bit) { case IR_MSG_DATA_ACCEPT: case IR_MSG_DATA_NOACCEPT: packToOutClass( - (((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes) * bitPerByte), // endBitOffset - (dataBuffer[0] & IR_MASK_MSG_INFO), // bytesToCheck - 3, // addressForCheck_Offset - &gotData, // objFine - &gotRawData // objWrong + (((dataBuffer[0] & IR_MASK_MSG_INFO) + crcBytes)), // packSize + gotData, // obj + PackOffsets { + 0, // msgOffset + 1, // addrFromOffset + 3, // addrToOffset + 5, // dataOffset + NULL // crcOffset + } ); break; @@ -400,29 +427,39 @@ void IR_Decoder::writeToBuffer(bool bit) { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// } -void IR_Decoder::packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, IDataPack* objFine, IDataPack* objWrong = nullptr) { - uint16_t crcValue; - IDataPack* objResult = nullptr; - if (i_dataBuffer == endBitOffset) { +void IR_Decoder::packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets) { + + if (i_dataBuffer == packSize * bitPerByte) { + PackOutInfo packInfo; #ifdef IRDEBUG_INFO Serial.print(" IN "); #endif - isCrcCorrect = crcCheck(bytesToCheck, crcValue); - if (isCrcCorrect && checkAddr(addressForCheckOffset, addressForCheckOffset + 1)) { - #ifdef IRDEBUG_INFO - Serial.println(" OK "); - #endif - objResult = objFine; + isCrcCorrect = crcCheck(packSize - crcBytes, packInfo.crc); + if (isCrcCorrect) { + // if ((addressForCheckOffset >= 0 ? checkAddr(addressForCheckOffset, addressForCheckOffset + 1) : 1)) {// адрес верен + // #ifdef IRDEBUG_INFO + // Serial.println(" OK "); + // #endif + + // } else { // адресс не верен + // #ifdef IRDEBUG_INFO + // Serial.println(" NOT MY "); + // #endif + // } + + packInfo.ptr = dataBuffer; + packInfo.packSize = packSize; + packInfo.offsets = offsets; + packInfo.offsets.crcOffset = packInfo.packSize - crcBytes; + packInfo.err = errors; + packInfo.rTime = riseSyncTime; + obj.set(packInfo); } else { - objResult = objWrong; #ifdef IRDEBUG_INFO - Serial.println(" NOT OK "); + Serial.println(" CRC WRONG "); #endif } - if (objWrong != nullptr) { - objResult->isAvaliable = true; - objResult->set(dataBuffer, bytesToCheck + crcBytes, crcValue, errors, riseSyncTime); - } + isRecive = false; } } diff --git a/IR_Decoder.h b/IR_Decoder.h index b7ad346..17f16cd 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -28,10 +28,11 @@ class IR_Decoder : private IR_FOX { friend IR_Encoder; public: uint16_t id; - Data gotData; /// @brief Контейнер с данными - Data gotRawData; - Accept gotAccept; /// @brief Контейнер с подтверждением - Request gotRequest; /// @brief Контейнер с запросом + + Data gotData = Data(id); /// @brief Контейнер с данными + Data gotRawData = Data(id); + Accept gotAccept = Accept(id); /// @brief Контейнер с подтверждением + Request gotRequest = Request(id); /// @brief Контейнер с запросом RawTune gotTune; /// @brief Контейнер с информацией подстройки const uint8_t isrPin; // Пин прерывания @@ -73,8 +74,6 @@ private: uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс - // bool HIGH_FIRST = true; //TODO: порядок приходящих битов - //////////////////////////////////////////////////////////////////////// volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов @@ -110,7 +109,7 @@ private: /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация /// @param Бит данных void writeToBuffer(bool); - void packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, IDataPack* objFine, IDataPack* objWrong = nullptr); + void packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets); //////////////////////////////////////////////////////////////////////// /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных @@ -128,4 +127,4 @@ private: #endif - }; \ No newline at end of file +}; \ No newline at end of file diff --git a/IR_Output.h b/IR_Output.h index 9a79ce7..ff5a9fe 100644 --- a/IR_Output.h +++ b/IR_Output.h @@ -4,130 +4,126 @@ class IR_Decoder; class IDataPack : protected IR_FOX { friend IR_Decoder; -protected: - inline static uint8_t data[dataByteSizeMax]{0}; - - bool isAvaliable = false; - - void* msgPtr = nullptr; - void* addrFromPtr = nullptr; - void* addrToPtr = nullptr; - void* dataPtr = nullptr; - void* crcPtr = nullptr; - - - - uint8_t msgByte = 0; - uint8_t packRawSize = 0; // полная длина пакета - - ErrorsStruct err; - uint16_t bitPeriod = 0; - uint16_t crcPackVal = 0; - uint16_t crcCalcVal = 0; - - ///////////// смещения //////////////// - uint8_t crcOffset; - //переопределяемые дочерними классами// - uint8_t msgOffset; - uint8_t addrFromOffset; - uint8_t addrToOffset; - uint8_t dataOffset; - ////////////////////////////////////// - - void set(uint8_t* ptr, uint8_t len, uint16_t crc, ErrorsStruct err, uint16_t rTime) { - memset(IDataPack::data, 0, dataByteSizeMax); - memcpy(data, ptr, min(len, dataByteSizeMax)); - packRawSize = len; - - bitPeriod = rTime; - err = err; - crcCalcVal = crc; - crcOffset = packRawSize - crcBytes; - - msgByte = *(uint8_t*)msgPtr; - isAvaliable = true; - - msgPtr = (data + msgOffset); - addrFromPtr = (data + addrFromOffset); - addrToPtr = (data + addrToOffset); - dataPtr = (data + dataOffset); - crcPtr = (data + crcOffset); - - } +public: + IDataPack(uint16_t id) : id(id) {}; public: bool avaliable() { return isAvaliable; }; - uint8_t getMsgInfo() { return msgByte & IR_MASK_MSG_INFO; }; - uint8_t getMsgType() { return (msgByte >> 5) & IR_MASK_MSG_TYPE; }; - uint8_t getMsgRAW() { return msgByte; }; + uint8_t getMsgInfo() { return msgPtr[0] & IR_MASK_MSG_INFO; }; + uint8_t getMsgType() { return (msgPtr[0] >> 5) & IR_MASK_MSG_TYPE; }; + uint8_t getMsgRAW() { return msgPtr[0]; }; uint16_t getErrorCount() { return err.all(); }; uint8_t getErrorLowSignal() { return err.lowSignal; }; uint8_t getErrorHighSignal() { return err.highSignal; }; uint8_t getErrorOther() { return err.other; }; + // uint16_t getCrcIN() { return crcPtr[0] << 8 | crcPtr[1]; }; + // uint16_t getCrcCALC() { return crcCalcVal; }; uint16_t getTunerTime() { return bitPeriod; }; void resetAvaliable() { isAvaliable = false; }; + +protected: + uint16_t id; + inline static uint8_t data[dataByteSizeMax] { 0 }; + + bool isAvaliable = false; + + uint8_t* msgPtr = nullptr; + uint8_t* addrFromPtr = nullptr; + uint8_t* addrToPtr = nullptr; + uint8_t* dataPtr = nullptr; + uint8_t* crcPtr = nullptr; + + ErrorsStruct err; + uint8_t packRawSize; + uint16_t bitPeriod; + uint16_t crcCalcVal; + + virtual bool checkAddress(PackOutInfo* packInfo) { return true; }; + + void set(PackOutInfo packInfo) { + + if (checkAddress(&packInfo)) { + onPackAddressCorrect(&packInfo); + } else { + onPackAddressIncorrect(&packInfo); + } + } + + virtual void onPackAddressCorrect(PackOutInfo* packInfo) { + memset(IDataPack::data, 0, dataByteSizeMax); + memcpy(data, packInfo->ptr, min(packInfo->packSize, dataByteSizeMax)); + err = packInfo->err; + bitPeriod = packInfo->rTime; + crcCalcVal = packInfo->crc; + packRawSize = packInfo->packSize; + + msgPtr = (data + packInfo->offsets.msgOffset); + addrFromPtr = (data + packInfo->offsets.addrFromOffset); + addrToPtr = (data + packInfo->offsets.addrToOffset); + dataPtr = (data + packInfo->offsets.dataOffset); + crcPtr = (data + packInfo->offsets.crcOffset); + + isAvaliable = true; + } + virtual void onPackAddressIncorrect(PackOutInfo* packInfo) {} + }; ////////////////////////////////////////////////////////////////////////// class Data : public IDataPack { + using IDataPack::IDataPack; public: - Data() { - msgOffset = 0; - addrFromOffset = 1; - addrToOffset = 3; - dataOffset = 5; - - } - - -public: - uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; - uint16_t getAddrTo() { return *(uint16_t*)addrToPtr; }; + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; uint8_t getDataSize() { return packRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; - uint8_t* getDataPrt() { return (uint8_t*)dataPtr; }; + uint8_t* getDataPrt() { return dataPtr; }; uint8_t getDataRawSize() { return packRawSize; }; uint8_t* getDataRawPtr() { return data; }; - uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; - uint16_t getCrcCALC() { return crcCalcVal; }; - bool isNeedAccept() { return ((msgByte >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; - ~Data() {}; + bool isNeedAccept() { return ((msgPtr[0] >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; + +private: + bool checkAddress(PackOutInfo* packInfo) override { + bool ret; + + uint8_t addrOffset = packInfo->offsets.addrToOffset; + uint16_t address = (packInfo->ptr[addrOffset] << 8) | (packInfo->ptr[addrOffset + 1]); + + checkaddressRuleApply(address, id, ret); + + return ret; + } + }; // class RawData : public Data { // }; class Accept : public IDataPack { + using IDataPack::IDataPack; public: - Accept() { - msgOffset = 0; - addrFromOffset = 1; - } - - uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; - uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; - uint16_t getCrcCALC() { return crcCalcVal; }; - + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; }; class Request : public IDataPack { + using IDataPack::IDataPack; public: - Request() { - msgOffset = 0; - addrFromOffset = 1; - addrToOffset = 3; - } - - uint16_t getAddrFrom() { return *(uint16_t*)addrFromPtr; }; - uint16_t getAddrTo() { return *(uint16_t*)addrToPtr; }; - uint16_t getCrcIN() { return *(uint16_t*)crcPtr; }; - uint16_t getCrcCALC() { return crcCalcVal; }; + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; }; -class RawTune : public IDataPack { +class RawTune { + friend IR_Decoder; public: - RawTune() { - msgOffset = 0; - } + bool avaliable() { return isAvaliable; }; + uint16_t getTunerTime() { return bitPeriod; }; + void resetAvaliable() { isAvaliable = false; }; +protected: + bool isAvaliable; + uint16_t bitPeriod; + void set(uint16_t time) { + bitPeriod = time; + isAvaliable = true; + } }; \ No newline at end of file diff --git a/IR_config.h b/IR_config.h index a106116..885be00 100644 --- a/IR_config.h +++ b/IR_config.h @@ -38,7 +38,7 @@ msg type:                                         // | xxx..... | = тип сообщения                                         // | ...xxxxx | = длина (максимум 31 бита)                                         //  ---------- */ -#define IR_MSG_ 0U // | 000..... | = Задний сигнал машинки +#define IR_MSG_BACK 0U // | 000..... | = Задний сигнал машинки ;// // | \\\x---- | = нужна ли адресация ;// // | \\\-xxxx | = длина данных (Равна нулю при отсутствии сквозных команд) #define IR_MSG_ACCEPT 1U // | 001..... | = подтверждение @@ -139,6 +139,14 @@ typedef uint16_t crc_t; class IR_FOX { public: + struct PackOffsets { + uint8_t msgOffset; + uint8_t addrFromOffset; + uint8_t addrToOffset; + uint8_t dataOffset; + uint8_t crcOffset; + }; + struct ErrorsStruct { uint8_t lowSignal; uint8_t highSignal; @@ -153,8 +161,24 @@ public: }; + struct PackOutInfo { + uint8_t* ptr; + uint8_t packSize; + PackOffsets offsets; + uint16_t crc; + ErrorsStruct err; + uint16_t rTime; + }; + protected: ErrorsStruct errors; + + void checkaddressRuleApply(uint16_t &address, uint16_t &id, bool &flag) { + flag = false; + flag |= address == id; + flag |= address >= IR_Broadcast; + } + uint8_t crc8(uint8_t* data, uint8_t start, uint8_t end, uint8_t poly) { //TODO: сделать возможность межбайтовой проверки uint8_t crc = 0xff; size_t i, j;