fix extra zero, docs and debag

This commit is contained in:
DashyFox 2024-01-24 16:13:03 +03:00
parent 56c207b058
commit d629b24864
3 changed files with 149 additions and 87 deletions

View File

@ -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) { 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 }; rawBuffer = new uint8_t[bufferRawSize] { 0 };
dataBuffer = rawBuffer;
prevRise = prevFall = prevPrevFall = prevPrevRise = 0; prevRise = prevFall = prevPrevFall = prevPrevRise = 0;
start_RX(); start_RX();
} }
@ -17,73 +18,117 @@ IR_Decoder::~IR_Decoder() {
} }
void IR_Decoder::writeToBuffer(bool bit) { void IR_Decoder::writeToBuffer(bool bit) {
if (!isBufferOverflow && !isPreamb) { if (isBufferOverflow || isPreamb) return;
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) { //TODO: Буффер переполнен! // Переключение флага, data или syncBit
if (bufBitPos == nextControlBit) {
} nextControlBit += (isData ? syncBits : bitPerByte);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////// isData = !isData;
//const auto testval = bufferBitSizeMax; Serial.print(" ");
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++;
} }
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) { uint8_t* IR_Decoder::getDataBuffer(bool reset = false) {
@ -149,10 +194,20 @@ bool IR_Decoder::crcCheck(uint8_t len) {
} }
void IR_Decoder::start_RX() { void IR_Decoder::start_RX() {
// Serial.println();
// Serial.println(printBytes(dataBuffer, dataByteSizeMax-1, BIN));
// Serial.println();
resetAvaliable(); resetAvaliable();
isBufferOverflow = false; isBufferOverflow = false;
memset(rawBuffer, 0x00, bufferRawSize); memset(rawBuffer, 0x00, bufferRawSize);
bufBitPos = 0; bufBitPos = 0;
isData = true;
i_dataBuffer = 0;
nextControlBit = bitPerByte;
i_syncBit = 0;
} }
void IR_Decoder::resetAvaliable() { void IR_Decoder::resetAvaliable() {
@ -308,14 +363,14 @@ void IR_Decoder::tick() {
void IR_Decoder::isr() { // в прерывании вызываем isr() void IR_Decoder::isr() { // в прерывании вызываем isr()
if (isPairSending) return; if (isPairSending) return;
frontBuffer[currentFrontBufferWriteIndex].next = nullptr; subBuffer[currentSubBufferIndex].next = nullptr;
frontBuffer[currentFrontBufferWriteIndex].dir = (PIND >> isrPin) & 1; subBuffer[currentSubBufferIndex].dir = (PIND >> isrPin) & 1;
frontBuffer[currentFrontBufferWriteIndex].time = micros(); subBuffer[currentSubBufferIndex].time = micros();
if (firstUnHandledFront == nullptr) { if (firstUnHandledFront == nullptr) {
firstUnHandledFront = &frontBuffer[currentFrontBufferWriteIndex]; // Если нет необработанных данных - добавляем их firstUnHandledFront = &subBuffer[currentSubBufferIndex]; // Если нет необработанных данных - добавляем их
} else { } else {
if (firstUnHandledFront == &frontBuffer[currentFrontBufferWriteIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его if (firstUnHandledFront == &subBuffer[currentSubBufferIndex]) { // Если контроллер не успел обработать новый сигнал, принудительно пропускаем его
firstUnHandledFront = firstUnHandledFront->next; firstUnHandledFront = firstUnHandledFront->next;
Serial.println(); Serial.println();
Serial.println("ERROR"); Serial.println("ERROR");
@ -324,14 +379,14 @@ void IR_Decoder::isr() { // в прерывании вызываем isr()
} }
if (lastFront == nullptr) { if (lastFront == nullptr) {
lastFront = &frontBuffer[currentFrontBufferWriteIndex]; lastFront = &subBuffer[currentSubBufferIndex];
} else { } else {
lastFront->next = &frontBuffer[currentFrontBufferWriteIndex]; lastFront->next = &subBuffer[currentSubBufferIndex];
lastFront = &frontBuffer[currentFrontBufferWriteIndex]; lastFront = &subBuffer[currentSubBufferIndex];
} }
currentFrontBufferWriteIndex == (subBuffer - 1) ? currentFrontBufferWriteIndex = 0 : currentFrontBufferWriteIndex++; currentSubBufferIndex == (subBufferSize - 1) ? currentSubBufferIndex = 0 : currentSubBufferIndex++;
} }

View File

@ -21,7 +21,7 @@
#define aroundRise(t) (riseTimeMin < t && t < riseTimeMax) #define aroundRise(t) (riseTimeMin < t && t < riseTimeMax)
#define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1 #define IR_timeout ((riseTimeMax * 8) + syncBits +1) // us // таймаут в 8 data + 3 sync + 1
#define subBuffer 5 //Буфер для складирования фронтов, пока их не обработают #define subBufferSize 15 //Буфер для складирования фронтов, пока их не обработают
class IR_Encoder; class IR_Encoder;
class IR_Decoder : private IR_FOX { class IR_Decoder : private IR_FOX {
@ -200,12 +200,14 @@ private:
const uint8_t bufferDataSize = dataByteSizeMax; // + crc const uint8_t bufferDataSize = dataByteSizeMax; // + crc
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
void noFunc(); void noFunc();
volatile uint8_t currentFrontBufferWriteIndex; volatile uint8_t currentSubBufferIndex; // Счетчик текущей позиции во вспомогательном буфере фронтов/спадов
// Структура для хранения времени и направления фронта/спада
struct FrontStorage { struct FrontStorage {
volatile uint32_t time; volatile uint32_t time; // Время
volatile bool dir; volatile bool dir; // Направление (true = ↑; false = ↓)
volatile FrontStorage* next; volatile FrontStorage* next; // Указатель на следующий связанный фронт/спад, или nullptr если конец
// Операторо присвоения
FrontStorage& operator= (FrontStorage& val) { FrontStorage& operator= (FrontStorage& val) {
this->next = val.next; this->next = val.next;
this->time = val.time; this->time = val.time;
@ -214,9 +216,9 @@ private:
return *this; return *this;
} }
}; };
volatile FrontStorage* lastFront = nullptr; volatile FrontStorage* lastFront = nullptr; // Указатель последнего фронта/спада
volatile FrontStorage* firstUnHandledFront = nullptr; volatile FrontStorage* firstUnHandledFront = nullptr; // Указатель первого необработанного фронта/спада
volatile FrontStorage frontBuffer[subBuffer]; volatile FrontStorage subBuffer[subBufferSize]; // вспомогательный буфер для хранения необработанных фронтов/спадов
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
uint8_t* rawBuffer = nullptr; uint8_t* rawBuffer = nullptr;
uint8_t* dataBuffer = nullptr; uint8_t* dataBuffer = nullptr;
@ -229,9 +231,14 @@ private:
private: private:
uint8_t* getDataBuffer(bool reset = false); uint8_t* getDataBuffer(bool reset = false);
bool crcCheck(uint8_t len); bool crcCheck(uint8_t len);
////////////////////////////////////////////////////////////////////////
inline void writeToBuffer(bool); bool isData = true; // Флаг относится ли бит к данным, или битам синхронизации
inline void start_RX(); uint16_t i_dataBuffer; // Счётчик буфера данных
uint8_t nextControlBit = bitPerByte; // Метка для смены флага isData
uint8_t i_syncBit; // Счётчик битов синхронизации
void writeToBuffer(bool);
////////////////////////////////////////////////////////////////////////
void start_RX();
void resetAvaliable(); void resetAvaliable();
uint16_t ceil_div(uint16_t, uint16_t); uint16_t ceil_div(uint16_t, uint16_t);

View File

@ -146,7 +146,7 @@ public:
case 2: case 2:
for (size_t i = 0; i < s * 8; i++) { for (size_t i = 0; i < s * 8; i++) {
if (i == control) { if (i == control) {
str += " "; str += " ";
control += bitPerByte; control += bitPerByte;
} }