diff --git a/IR_Decoder.cpp b/IR_Decoder.cpp index f9257e6..6803bcc 100644 --- a/IR_Decoder.cpp +++ b/IR_Decoder.cpp @@ -4,15 +4,13 @@ #define IRDEBUG_INFO #define checkAddr(h, l) (\ - ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == addrSelf) || \ + ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) == id) || \ ((uint16_t)((dataBuffer[h] << 8) | dataBuffer[l]) >= IR_Broadcast)\ ) -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 }; +IR_Decoder::IR_Decoder(const uint8_t isrPin, uint16_t addr, IR_Encoder* encPair = nullptr) : isrPin(isrPin), id(addr), encoder(encPair) { 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(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, // addressForCheckOffset - &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, // addressForCheckOffset - &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, // addressForCheckOffset - &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, InputData* objFine, InputData* objWrong = nullptr) { - uint16_t crcValue; - InputData* 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; } } @@ -442,7 +479,9 @@ bool IR_Decoder::crcCheck(uint8_t len, crc_t& crc) { dataBuffer[len + 1] == (crc & 0xFF) ) { crcOK = true; - } else { crcOK = false; } + } else { + crcOK = false; + } return crcOK; diff --git a/IR_Decoder.h b/IR_Decoder.h index 659515b..17f16cd 100644 --- a/IR_Decoder.h +++ b/IR_Decoder.h @@ -1,5 +1,6 @@ #pragma once #include "IR_config.h" +#include "IR_Output.h" //#define IRDEBUG @@ -26,194 +27,54 @@ class IR_Encoder; class IR_Decoder : private IR_FOX { friend IR_Encoder; public: - uint16_t addrSelf; + uint16_t id; + + 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; // Пин прерывания + + ////////////////////////////////////////////////////////////////////////// /// @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 Функция прерывания - void isr(); - - /// @brief Обработка приёмника, необходима для работы - void tick(); - + void isr(); ///@brief Функция прерывания + void tick(); /// @brief Обработка приёмника, необходима для работы // @return Буффер переполнился bool isOverflow() { return isBufferOverflow; }; + /// @brief Флаг приёма /// @return Возвращает true, если происходит приём пакета bool isReciving() { return isRecive; }; + // @brief Слушатель для работы isReciving() void listen(); ////////////////////////////////////////////////////////////////////////// - struct ErrorsStruct { - uint8_t lowSignal; - uint8_t highSignal; - uint8_t other; - - void reset() { - lowSignal = 0; - highSignal = 0; - other = 0; - } - uint16_t all() { return lowSignal + highSignal + other; } - - } errors; - -public: - class InputData : protected IR_FOX { - friend IR_Decoder; - protected: - bool _isAvaliable = false; - uint8_t _msgType = 0; - uint16_t _addrFrom = 0; - uint16_t _addrTo = 0; - uint8_t _data[dataByteSizeMax]; - uint8_t _dataRawSize = 0; - uint16_t _crcPackVal = 0; - uint16_t _crcCalcVal = 0; - ErrorsStruct _err; - uint16_t _bitPeriod = 0; - - void _set(uint8_t* ptr, uint8_t len, uint16_t crc, ErrorsStruct err, uint16_t rTime) { - _crcCalcVal = crc; - _dataRawSize = len; - _err = err; - _bitPeriod = rTime; - memset(_data, 0, dataByteSizeMax); - memcpy(_data, ptr, min(len, dataByteSizeMax)); - _msgType = _data[0]; - ini(); - _isAvaliable = true; - } - - private: - virtual void ini(); - - public: - bool avaliable() { return _isAvaliable; }; - uint8_t msgInfo() { return _msgType & IR_MASK_MSG_INFO; }; - uint8_t msgType() { return (_msgType >> 5) & IR_MASK_MSG_TYPE; }; - uint8_t msgRAW() { return _msgType; }; - uint16_t errorCount() { return _err.all(); }; - uint8_t errorLowSignal() { return _err.lowSignal; }; - uint8_t errorHighSignal() { return _err.highSignal; }; - uint8_t errorOther() { return _err.other; }; - uint16_t crcIN() { return _crcPackVal; }; - uint16_t crcCALC() { return _crcCalcVal; }; - uint16_t tunerTime() { return _bitPeriod; }; - void resetAvaliable() { _isAvaliable = false; }; - }; - - ////////////////////////////////////////////////////////////////////////// - - class Data : public InputData { - public: - uint16_t addrFrom() { return _addrFrom; }; - uint16_t addrTo() { return _addrTo; }; - uint8_t dataSize() { return _dataRawSize - (msgBytes + addrBytes + addrBytes + crcBytes); }; - uint8_t* data() { return &_data[msgBytes + addrBytes + addrBytes]; }; - uint8_t dataRawSize() { return _dataRawSize; }; - uint8_t* dataRaw() { return _data; }; - bool isNeedAccept() { return ((_msgType >> 5) & IR_MASK_MSG_TYPE) == IR_MSG_DATA_ACCEPT; }; - String printRawData(uint8_t mode = 10) { - return printBytes(dataRaw(), dataRawSize(), mode); - } - String printData(uint8_t mode = 10) { - return printBytes(data(), dataSize(), mode); - } - ~Data() {}; - private: - void ini() override { - _addrFrom = (_data[1] << 8) | _data[2]; - _addrTo = (_data[3] << 8) | _data[4]; - _crcPackVal = (_data[_dataRawSize - 2] << 8) | _data[_dataRawSize - 1]; - } - }; - - // class RawData : public Data { - // }; - - class Accept : public InputData { - public: - uint16_t addrFrom() { return _addrFrom; }; - - private: - void ini() override { - _addrFrom = (_data[1] << 8) | _data[2]; - _crcPackVal = (_data[3] << 8) | _data[4]; - } - }; - - class Request : public Accept { - public: - uint16_t addrTo() { return _addrTo; }; - private: - void ini() override { - _addrFrom = (_data[1] << 8) | _data[2]; - _addrTo = (_data[3] << 8) | _data[4]; - _crcPackVal = (_data[5] << 8) | _data[6]; - } - }; - - class RawTune { - friend IR_Decoder; - private: - bool _isAvaliable = false; - uint16_t _errCount = 0; - uint16_t _tune = 0; - public: - bool avaliable() { return _isAvaliable; }; - uint16_t getTune() { return _tune; }; - uint16_t errorCount() { return _errCount; }; - void resetAvaliable() { _isAvaliable = false; }; - private: - void _set(uint16_t val) { - _tune = val; - _isAvaliable = true; - } - }; - - /// @brief Контейнер с данными - Data gotData; - Data gotRawData; - /// @brief Контейнер с подтверждением - Accept gotAccept; - /// @brief Контейнер с запросом - Request gotRequest; - /// @brief Контейнер с информацией подстройки - RawTune gotTune; - - const uint8_t isrPin; // Пин прерывания - private: - - IR_Encoder* encoder; // Указатель на парный передатчик volatile uint16_t isPairSending = 0; // Флаг передачи парного передатчика - - volatile bool isRecive = false; // Флаг приёма - + volatile bool isPreamb = false; // флаг начальной последовости bool isWaitingAccept = false; // Флаг ожидания подтверждения - uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение - - uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс - bool isCrcCorrect = false; // Флаг корректности crc bool isBufferOverflow = false; // Флаг переполнения буффера данных bool isWrongPack = false; // Флаг битого пакета - volatile bool isPreamb = false; // флаг начальной последовости - bool HIGH_FIRST = true; //TODO: порядок приходящих битов + uint16_t addrWaitingFrom = 0; // Адрес, от кого ожидается подтверждение + uint16_t riseSyncTime = bitTime; // Подстраиваемое время бита в мкс //////////////////////////////////////////////////////////////////////// - void noFunc(); volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов struct FrontStorage { // Структура для хранения времени и направления фронта/спада @@ -237,6 +98,7 @@ private: /// @param crc Результат рассчёта crc (Выходной параметр) /// @return true если crc верно bool crcCheck(uint8_t len, uint16_t& crc); + //////////////////////////////////////////////////////////////////////// bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации uint16_t i_dataBuffer; // Счётчик буфера данных @@ -247,13 +109,12 @@ private: /// @brief Запиь бита в буффер, а так же проверка битов синхранизации и их фильтрация /// @param Бит данных void writeToBuffer(bool); - void packToOutClass(uint8_t endBitOffset, uint8_t bytesToCheck, uint8_t addressForCheckOffset, InputData* objFine, InputData* objWrong = nullptr); + void packToOutClass(uint8_t packSize, IDataPack& obj, PackOffsets offsets); //////////////////////////////////////////////////////////////////////// /// @brief Установка и сброс начальных значений и флагов в готовность к приёму данных void start_RX(); - /// @brief Целочисленное деление с округлением вверх /// @param val Значение /// @param divider Делитель diff --git a/IR_Encoder.cpp b/IR_Encoder.cpp index 0eaf6b3..64a9837 100644 --- a/IR_Encoder.cpp +++ b/IR_Encoder.cpp @@ -106,7 +106,46 @@ void IR_Encoder::sendRequest(uint16_t addrTo, uint8_t addInfo) { rawSend(sendBuffer, msgBytes + addrBytes + addrBytes + crcBytes); } +void IR_Encoder::sendBack(uint8_t* data = nullptr, uint8_t len = 0){ + _sendBack(false, 0, data, len); +} +void IR_Encoder::sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0){ + _sendBack(true, addrTo, data, len); +} + +void IR_Encoder::_sendBack(bool isAdressed ,uint16_t addrTo,uint8_t* data, uint8_t len){ + if (len > bytePerPack) { return; } + memset(sendBuffer, 0x00, dataByteSizeMax); + constexpr uint8_t dataStart = msgBytes + addrBytes; + + uint8_t packSize = msgBytes + addrBytes + len + crcBytes; + uint8_t msgType = + (IR_MSG_BACK << 5) | (isAdressed << 4U) | ((packSize - crcBytes) & (IR_MASK_MSG_INFO>>1)); + + // формирование массива + // msg_type + sendBuffer[0] = msgType; + + // addr_from or data + sendBuffer[1] = id >> 8 & 0xFF; + sendBuffer[2] = id & 0xFF; + + // addr_to + sendBuffer[3] = addrTo >> 8 & 0xFF; + sendBuffer[4] = addrTo & 0xFF; + + for (uint16_t i = dataStart; i < dataStart + len; i++) { + sendBuffer[i] = ((uint8_t*)data)[i - dataStart]; + } + + // data crc + sendBuffer[packSize - crcBytes] = crc8(sendBuffer, 0, packSize - crcBytes, poly1) & 0xFF; + sendBuffer[packSize - crcBytes + 1] = crc8(sendBuffer, 0, packSize - crcBytes + 1, poly2) & 0xFF; + + // отправка + rawSend(sendBuffer, packSize); +} void IR_Encoder::setDecoder_isSending() { if (decodersCount) { diff --git a/IR_Encoder.h b/IR_Encoder.h index 8d86781..2712b3b 100644 --- a/IR_Encoder.h +++ b/IR_Encoder.h @@ -43,17 +43,19 @@ public: } void IR_Encoder::setBlindDecoders(IR_Decoder* decoders [], uint8_t count); - // template - // void sendData(uint16_t addrTo, T& data, bool needAccept = false); + void rawSend(uint8_t* ptr, uint8_t len); void sendData(uint16_t addrTo, uint8_t* data, uint8_t len, 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 sendBack(uint8_t* data = nullptr, uint8_t len = 0); + void sendBackTo(uint16_t addrTo, uint8_t* data = nullptr, uint8_t len = 0); void isr(); ~IR_Encoder(); volatile bool ir_out_virtual; private: + void IR_Encoder::_sendBack(bool isAdressed, uint16_t addrTo, uint8_t* data, uint8_t len); + void IR_Encoder::setDecoder_isSending(); void sendByte(uint8_t byte, bool* prev, bool LOW_FIRST); void addSync(bool* prev, bool* next); @@ -101,24 +103,10 @@ private: (bitPauseTakts) * 2 - 1 }; uint8_t* currentBitSequence = bitLow; - - // uint8_t bitSequence[2]; - volatile SignalPart signal; }; -//////////////////////////////////////////////////////////////////////////////////////////////// -// template -// void IR_Encoder::sendData(uint16_t addrTo, T& data, bool needAccept = false) { // TODO: переделать логику LOW_FIRST -// uint8_t len = sizeof(T); -// uint8_t packSize = msgBytes + addrBytes + addrBytes + len + crcBytes; - -// uint8_t msgType = -// ((needAccept ? IR_MSG_DATA_ACCEPT : IR_MSG_DATA_NOACCEPT) << 5) | ((packSize - crcBytes) & IR_MASK_MSG_INFO); - -// _sendData(addrTo, data, len, msgType); -// } diff --git a/IR_Output.h b/IR_Output.h new file mode 100644 index 0000000..ff5a9fe --- /dev/null +++ b/IR_Output.h @@ -0,0 +1,129 @@ +#pragma once +#include "IR_config.h" +class IR_Decoder; + +class IDataPack : protected IR_FOX { + friend IR_Decoder; +public: + IDataPack(uint16_t id) : id(id) {}; + +public: + bool avaliable() { return isAvaliable; }; + 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: + 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 dataPtr; }; + uint8_t getDataRawSize() { return packRawSize; }; + uint8_t* getDataRawPtr() { return 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: + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; +}; + +class Request : public IDataPack { + using IDataPack::IDataPack; +public: + uint16_t getAddrFrom() { return addrFromPtr[0] << 8 | addrFromPtr[1]; }; + uint16_t getAddrTo() { return addrToPtr[0] << 8 | addrToPtr[1]; }; +}; + +class RawTune { + friend IR_Decoder; +public: + 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 ba61120..cc0ccfd 100644 --- a/IR_config.h +++ b/IR_config.h @@ -22,10 +22,10 @@ IR_MSG_ACCEPT с адреса 0 воспринимается всеми устр /```````````````````````````````````````````````` data pack `````````````````````````````````````````````\                                                                                                                                             {``````````} [````````````````````````] [````````````````````] [````````````````````````] [``````````````] -{ msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ] +{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ] {..........} [........................] [....................] [........................] [..............]                                                                                                            -{ aka size } [addr_self_H][addr_self_L] [addr_to_H][addr_to_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ] +{ aka size } [addr_from_H][addr_from_L] [addr_to_H][addr_to_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ] |     0           1            2              3         4          5                         |       |     \____________________________________________________________________________________________/       |     |                                                                                                    |     @@ -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..... | = подтверждение @@ -55,10 +55,10 @@ msg type: /```````````````````` подтверждение ```````````````````\      /``````````````````````````````````````` запрос ``````````````````````````````````\                                                                                                                        {``````````} [````````````````````````] [``````````````]      {``````````} [````````````````````````] [````````````````````````] [``````````````] -{ msg type } [ addr_self uint16_t ] [ CRC Bytes ]      { msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] +{ msg type } [ addr_from uint16_t ] [ CRC Bytes ]      { msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [ CRC Bytes ] {..........} [........................] [..............]      {..........} [........................] [........................] [..............]                                                                                                                                                   -{ 001..... } [addr_self_H][addr_self_L] [ crc1 ][ crc2 ]      { 010..... } [addr_self_H][addr_self_L] [addr_self_H][addr_self_L] [ crc1 ][ crc2 ] +{ 001..... } [addr_from_H][addr_from_L] [ crc1 ][ crc2 ]      { 010..... } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [ crc1 ][ crc2 ] |     0            1           2           3       4          |     0            1           2              3           4           5       6     \__________________________________________/       |          \_____________________________________________________________________/       |     |                                                  |          |                                                                             |     @@ -69,10 +69,10 @@ msg type: /`````````````````````` Задний сигнал машинки без адресации ``````````````````````\        В (IR_MASK_MSG_INFO & 15U) содержится количество байт                                                                                            сквозных команд, максимум 15 {``````````} [````````````````````````] [````````````````````````] [``````````````]        Если полезных байт информации нет, отправляется один -{ msg type } [ addr_self uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей +{ msg type } [ addr_from uint16_t ] [====== data bytes ======] [ CRC Bytes ]        байт нулей {..........} [........................] [........................] [..............]                                                                                                     -{ 0000xxxx } [addr_self_H][addr_self_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         +{ 0000xxxx } [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]         |     0           1            2            3                         |       |             \_____________________________________________________________________/       |             |                                                                             |             @@ -83,10 +83,10 @@ msg type: /```````````````````````````````````` Задний сигнал машинки с адресацией ````````````````````````````````````\                                                                                       {``````````} [````````````````````````] [````````````````````````] [````````````````````````] [``````````````]  -{ msg type } [ addr_self uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  +{ msg type } [ addr_from uint16_t ] [ addr_to uint16_t ] [====== data bytes ======] [ CRC Bytes ]  {..........} [........................] [........................] [........................] [..............]                                                                                                                  -{ 0001xxxx } [addr_self_H][addr_self_L] [addr_self_H][addr_self_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  +{ 0001xxxx } [addr_from_H][addr_from_L] [addr_from_H][addr_from_L] [data_H][data_n..][data_L] [ crc1 ][ crc2 ]  |     0           1            2              3           4            5                         |       |      \________________________________________________________________________________________________/       |      |                                                                                                        |      @@ -138,9 +138,47 @@ typedef uint16_t crc_t; #define tolerance 300U class IR_FOX { -private: - bool isSending = false; +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; + uint8_t other; + + void reset() { + lowSignal = 0; + highSignal = 0; + other = 0; + } + uint16_t all() { return lowSignal + highSignal + other; } + + }; + + 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; @@ -155,41 +193,5 @@ protected: } return crc; } - // public: - /// @brief Вывод массива байт в строковом формате - /// @param d Указатель на массив - /// @param s Размер массива - /// @param mode Формат вывода DEC, BIN - /// @return Готовая для вывода строка - String printBytes(uint8_t* d, uint8_t s, uint8_t mode = 10) { - String str = ""; - uint8_t control = bitPerByte; - uint8_t* _data = d; - switch (mode) { - case 2: - for (size_t i = 0; i < s * 8; i++) { - if (i == control) { - str += " "; - control += bitPerByte; - } - - str += _data[(i / 8)] >> (7 - (i % 8)) & 1; - } - break; - case 10: - for (size_t i = 0; i < s; i++) { - str += _data[i]; - str += " "; - } - - break; - - default: - break; - } - - str += " "; - return str; - } };